From 3627d96175c1424916d353c5a06c25883a338703 Mon Sep 17 00:00:00 2001 From: gmorel Date: Wed, 18 Sep 2013 10:07:57 +0200 Subject: [PATCH 01/43] WIP : Upload management --- core/lib/Thelia/Config/Resources/config.xml | 1 + .../Thelia/Config/Resources/routing/admin.xml | 4 + .../Controller/Admin/CategoryController.php | 60 +++++++++++ .../Form/CategoryPictureCreationForm.php | 100 ++++++++++++++++++ core/lib/Thelia/Model/CategoryImage.php | 44 ++++++++ templates/admin/default/category-edit.html | 25 +++++ 6 files changed, 234 insertions(+) create mode 100644 core/lib/Thelia/Form/CategoryPictureCreationForm.php diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 41e49d7d7..db2b1db82 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -54,6 +54,7 @@
+ diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index af7c950af..8f2e54f86 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -100,6 +100,10 @@ Thelia\Controller\Admin\CategoryController::addRelatedContentAction + + Thelia\Controller\Admin\CategoryController::addRelatedPictureAction + + Thelia\Controller\Admin\CategoryController::deleteRelatedContentAction diff --git a/core/lib/Thelia/Controller/Admin/CategoryController.php b/core/lib/Thelia/Controller/Admin/CategoryController.php index 8c74c31ec..1c7854416 100755 --- a/core/lib/Thelia/Controller/Admin/CategoryController.php +++ b/core/lib/Thelia/Controller/Admin/CategoryController.php @@ -27,6 +27,7 @@ use Thelia\Core\Event\CategoryDeleteEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\CategoryUpdateEvent; use Thelia\Core\Event\CategoryCreateEvent; +use Thelia\Form\CategoryPictureCreationForm; use Thelia\Model\CategoryQuery; use Thelia\Form\CategoryModificationForm; use Thelia\Form\CategoryCreationForm; @@ -306,6 +307,39 @@ class CategoryController extends AbstractCrudController $this->redirectToEditionTemplate(); } + /** + * Add category pictures + * + * @return \Symfony\Component\HttpFoundation\Response + */ + public function addRelatedPictureAction() + { + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.categories.update")) { + return $response; + } + +// $content_id = intval($this->getRequest()->get('content_id')); +// +// if ($content_id > 0) { +// +// $event = new CategoryAddContentEvent( +// $this->getExistingObject(), +// $content_id +// ); +// +// try { +// $this->dispatch(TheliaEvents::CATEGORY_ADD_CONTENT, $event); +// } +// catch (\Exception $ex) { +// // Any error +// return $this->errorPage($ex); +// } +// } + + $this->redirectToEditionTemplate(); + } + public function deleteRelatedContentAction() { // Check current user authorization @@ -331,4 +365,30 @@ class CategoryController extends AbstractCrudController $this->redirectToEditionTemplate(); } + + /** + * @todo remove + * @return Symfony\Component\HttpFoundation\Response|void + */ + public function updateAction() + { + var_dump('updateAction'); + if ($this->getRequest()->isMethod('POST')) { + var_dump('getRequest', $this->getRequest()->files); + // Create the form from the request + $creationForm = new CategoryPictureCreationForm($this->getRequest()); + + // Check the form against constraints violations + $form = $this->validateForm($creationForm, 'POST'); + var_dump('$form', $form); + + // Get the form field values + $data = $form->getData(); + var_dump('$data', $data); + } + + + return parent::updateAction(); + } + } diff --git a/core/lib/Thelia/Form/CategoryPictureCreationForm.php b/core/lib/Thelia/Form/CategoryPictureCreationForm.php new file mode 100644 index 000000000..2dffc61c3 --- /dev/null +++ b/core/lib/Thelia/Form/CategoryPictureCreationForm.php @@ -0,0 +1,100 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints\Image; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; + +class CategoryPictureCreationForm extends BaseForm +{ + protected function buildForm() + { + $this->formBuilder +// ->add('alt') + ->add('file', 'file', array( + 'constraints' => array( + new NotBlank(), + new Image( + array( + 'minWidth' => 200, + 'maxWidth' => 400, + 'minHeight' => 200, + 'maxHeight' => 400, + ) + ) + ))) +// ->add('category_id', 'model', array( +// 'disabled' => false, +// 'class' => 'Thelia\Model\ProductImage' +// )) +// ->add('position', 'integer', array( +// 'constraints' => array( +// new NotBlank() +// ) +// )) + ->add('title', 'text', array( + 'constraints' => array( +// new NotBlank() + ), +// 'label' => Translator::getInstance()->trans('Category picture title *'), +// 'label_attr' => array( +// 'for' => 'title' +// ) + )) +// ->add('description', 'text', array( +// 'constraints' => array( +// new NotBlank() +// ), +// 'label' => Translator::getInstance()->trans('Category picture description *'), +// 'label_attr' => array( +// 'for' => 'description' +// ) +// )) +// ->add('chapo', 'text', array( +// 'constraints' => array( +// new NotBlank() +// ), +// 'label' => Translator::getInstance()->trans('Category picture chapo *'), +// 'label_attr' => array( +// 'for' => 'chapo' +// ) +// )) +// ->add('postscriptum', 'text', array( +// 'constraints' => array( +// new NotBlank() +// ), +// 'label' => Translator::getInstance()->trans('Category picture postscriptum *'), +// 'label_attr' => array( +// 'for' => 'postscriptum' +// ) +// )) + + ; + } + + public function getName() + { + return 'thelia_category_picture_creation'; + } +} diff --git a/core/lib/Thelia/Model/CategoryImage.php b/core/lib/Thelia/Model/CategoryImage.php index 5bf964e10..aca77615a 100755 --- a/core/lib/Thelia/Model/CategoryImage.php +++ b/core/lib/Thelia/Model/CategoryImage.php @@ -25,4 +25,48 @@ class CategoryImage extends BaseCategoryImage return true; } + + /** + * Get picture absolute path + * + * @return null|string + */ + public function getAbsolutePath() + { + return null === $this->file + ? null + : $this->getUploadRootDir().'/'.$this->file; + } + + /** + * Get picture web path + * + * @return null|string + */ + public function getWebPath() + { + return null === $this->file + ? null + : $this->getUploadDir().'/'.$this->file; + } + + /** + * The absolute directory path where uploaded + * documents should be saved + * @return string + */ + protected function getUploadRootDir() + { + return __DIR__.'/../../../../../'.$this->getUploadDir(); + } + + /** + * Get rid of the __DIR__ so it doesn't screw up + * when displaying uploaded doc/image in the view. + * @return string + */ + protected function getUploadDir() + { + return 'local/media/images/category'; + } } diff --git a/templates/admin/default/category-edit.html b/templates/admin/default/category-edit.html index 723cf8242..6d1c4a9c2 100755 --- a/templates/admin/default/category-edit.html +++ b/templates/admin/default/category-edit.html @@ -246,6 +246,31 @@
+ image + {form name="thelia.admin.category.picture.creation"} + + {form_hidden_fields form=$form} + + + {form_field form=$form field='title'} +
+ + + {if $error}{$message}{/if} +
+ {/form_field} + + {form_field form=$form field='file'} +
+ + + {if $error}{$message}{/if} +
+ {/form_field} + + + + {/form}
From e27b3cfbaee509a2e6edfc740524f846f72c6a79 Mon Sep 17 00:00:00 2001 From: franck Date: Fri, 20 Sep 2013 15:54:50 +0200 Subject: [PATCH 02/43] Working catalog branch --- core/lib/Thelia/Action/Product.php | 72 + .../Controller/Admin/ProductController.php | 74 +- core/lib/Thelia/Core/Event/TheliaEvents.php | 24 +- .../Core/Template/Loop/FeatureValue.php | 50 +- .../lib/Thelia/Core/Template/Loop/Product.php | 1 + .../Model/Base/AttributeCombination.php | 103 +- .../Model/Base/AttributeCombinationQuery.php | 33 +- core/lib/Thelia/Model/Base/FeatureProduct.php | 48 +- .../Thelia/Model/Base/FeatureProductQuery.php | 28 +- core/lib/Thelia/Model/Base/OrderProduct.php | 1052 +++++-- .../Thelia/Model/Base/OrderProductQuery.php | 422 ++- core/lib/Thelia/Model/FeatureProduct.php | 60 +- .../Map/AttributeCombinationTableMap.php | 36 +- .../Model/Map/FeatureProductTableMap.php | 30 +- .../Thelia/Model/Map/OrderProductTableMap.php | 112 +- .../Model/Map/ProductSaleElementsTableMap.php | 2 +- core/lib/Thelia/Model/Map/TaxI18nTableMap.php | 2 +- .../Thelia/Model/Map/TaxRuleI18nTableMap.php | 2 +- install/faker.php | 2 +- install/thelia.sql | 70 +- local/config/schema.xml | 2482 +++++++++-------- .../default/ajax/template-attribute-list.html | 2 +- .../default/ajax/template-feature-list.html | 2 +- templates/admin/default/category-edit.html | 4 +- templates/admin/default/feature-edit.html | 8 +- templates/admin/default/folder-edit.html | 4 +- .../standard-description-form-fields.html | 2 +- templates/admin/default/product-edit.html | 377 +-- 28 files changed, 3112 insertions(+), 1992 deletions(-) diff --git a/core/lib/Thelia/Action/Product.php b/core/lib/Thelia/Action/Product.php index 69a07c157..8865f25b2 100644 --- a/core/lib/Thelia/Action/Product.php +++ b/core/lib/Thelia/Action/Product.php @@ -48,6 +48,11 @@ use Thelia\Model\AccessoryQuery; use Thelia\Model\Accessory; use Thelia\Core\Event\ProductAddAccessoryEvent; use Thelia\Core\Event\ProductDeleteAccessoryEvent; +use Thelia\Core\Event\FeatureProductUpdateEvent; +use Thelia\Model\FeatureProduct; +use Thelia\Model\FeatureQuery; +use Thelia\Core\Event\FeatureProductDeleteEvent; +use Thelia\Model\FeatureProductQuery; class Product extends BaseAction implements EventSubscriberInterface { @@ -247,6 +252,70 @@ class Product extends BaseAction implements EventSubscriberInterface } } + public function updateFeatureProductValue(FeatureProductUpdateEvent $event) { + + // If the feature is not free text, it may have one ore more values. + // If the value exists, we do not change it + // If the value does not exists, we create it. + // + // If the feature is free text, it has only a single value. + // Etiher create or update it. + + $featureProductQuery = FeatureProductQuery::create() + ->filterByFeatureId($event->getFeatureId()) + ->filterByProductId($event->getProductId()) + ; + + if ($event->getIsTextValue() !== true) { + $featureProductQuery->filterByFeatureAvId($event->getFeatureValue()); + } + + $featureProduct = $featureProductQuery->findOne(); +echo "
create or update: f=".$event->getFeatureId().", p=".$event->getProductId(); + + if ($featureProduct == null) { +echo " Create !"; + $featureProduct = new FeatureProduct(); + + $featureProduct + ->setDispatcher($this->getDispatcher()) + + ->setProductId($event->getProductId()) + ->setFeatureId($event->getFeatureId()) + + ; + } + else echo " Update !"; + + if ($event->getIsTextValue() == true) { + $featureProduct->setFreeTextValue($event->getFeatureValue()); + } + else { + $featureProduct->setFeatureAvId($event->getFeatureValue()); + } + + $featureProduct->save(); + + $event->setFeatureProduct($featureProduct); + } + + public function deleteFeatureProductValue(FeatureProductDeleteEvent $event) { + + $featureProduct = new FeatureProduct(); + + $featureProduct + ->setDispatcher($this->getDispatcher()) + + ->setProductId($event->getProductId()) + ->setFeatureId($event->getFeatureId()) + + ->delete(); + ; +echo "
Delete p=".$event->getProductId()." f=".$event->getFeatureId(); + + $event->setFeatureProduct($featureProduct); + } + /** * {@inheritDoc} */ @@ -266,6 +335,9 @@ class Product extends BaseAction implements EventSubscriberInterface TheliaEvents::PRODUCT_ADD_ACCESSORY => array("addAccessory", 128), TheliaEvents::PRODUCT_REMOVE_ACCESSORY => array("removeAccessory", 128), + + TheliaEvents::PRODUCT_FEATURE_UPDATE_VALUE => array("updateFeatureProductValue", 128), + TheliaEvents::PRODUCT_FEATURE_DELETE_VALUE => array("deleteFeatureProductValue", 128), ); } } diff --git a/core/lib/Thelia/Controller/Admin/ProductController.php b/core/lib/Thelia/Controller/Admin/ProductController.php index 27c559442..cefed04ff 100644 --- a/core/lib/Thelia/Controller/Admin/ProductController.php +++ b/core/lib/Thelia/Controller/Admin/ProductController.php @@ -43,6 +43,10 @@ use Thelia\Model\AccessoryQuery; use Thelia\Model\CategoryQuery; use Thelia\Core\Event\ProductAddAccessoryEvent; use Thelia\Core\Event\ProductDeleteAccessoryEvent; +use Thelia\Core\Event\FeatureProductUpdateEvent; +use Thelia\Model\FeatureQuery; +use Thelia\Core\Event\FeatureProductDeleteEvent; +use Thelia\Model\FeatureTemplateQuery; /** * Manages products @@ -443,7 +447,7 @@ class ProductController extends AbstractCrudController } /** - * Update accessory position (only for objects whichsupport that) + * Update accessory position */ public function updateAccessoryPositionAction() { @@ -474,4 +478,72 @@ class ProductController extends AbstractCrudController $this->redirectToEditionTemplate(); } + /** + * Update product attributes and features + */ + public function updateAttributesAndFeaturesAction($productId) { + + // et all features for the product's template + $product = ProductQuery::create()->findPk($productId); + + if ($product != null) { + + $featureTemplate = FeatureTemplateQuery::create()->filterByTemplateId($product->getTemplateId())->find(); + + if ($featureTemplate !== null) { + // Get all features for the template attached to this product + $allFeatures = FeatureQuery::create() + ->filterByFeatureTemplate($featureTemplate) + ->find(); + + $updatedFeatures = array(); + + // Update all features values + $featureValues = $this->getRequest()->get('feature_value', array()); +print_r($featureValues); + foreach($featureValues as $featureId => $featureValueList) { + + // Delete all values for this feature. + $event = new FeatureProductDeleteEvent($productId, $featureId); + + $this->dispatch(TheliaEvents::PRODUCT_FEATURE_DELETE_VALUE, $event); + + // Add all selected values + foreach($featureValueList as $featureValue) { + $event = new FeatureProductUpdateEvent($productId, $featureId, $featureValue); + + $this->dispatch(TheliaEvents::PRODUCT_FEATURE_UPDATE_VALUE, $event); + } + + $updatedFeatures[] = $featureId; + } + + // Update then features text values + $featureTextValues = $this->getRequest()->get('feature_text_value', array()); +print_r($featureTextValues); + foreach($featureTextValues as $featureId => $featureValue) { + + // considere empty text as empty feature value (e.g., we will delete it) + if (empty($featureValue)) continue; + + $event = new FeatureProductUpdateEvent($productId, $featureId, $featureValue, true); + + $this->dispatch(TheliaEvents::PRODUCT_FEATURE_UPDATE_VALUE, $event); + + $updatedFeatures[] = $featureId; + } + + // Delete features which don't have any values + foreach($allFeatures as $feature) { + if (! in_array($feature->getId(), $updatedFeatures)) { + $event = new FeatureProductDeleteEvent($productId, $feature->getId()); +echo "delete $productId, ".$feature->getId()." - "; + $this->dispatch(TheliaEvents::PRODUCT_FEATURE_DELETE_VALUE, $event); + } + } + } + } + + $this->redirectToEditionTemplate(); + } } diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 75f5314f0..aee3d81e9 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -170,8 +170,8 @@ final class TheliaEvents const BEFORE_CREATECATEGORY_ASSOCIATED_CONTENT = "action.before_createCategoryAssociatedContent"; const AFTER_CREATECATEGORY_ASSOCIATED_CONTENT = "action.after_createCategoryAssociatedContent"; - const BEFORE_DELETECATEGORY_ASSOCIATED_CONTENT = "action.before_deleteCategoryAssociatedContenty"; - const AFTER_DELETECATEGORY_ASSOCIATED_CONTENT = "action.after_deleteproduct_accessory"; + const BEFORE_DELETECATEGORY_ASSOCIATED_CONTENT = "action.before_deleteCategoryAssociatedContent"; + const AFTER_DELETECATEGORY_ASSOCIATED_CONTENT = "action.after_deleteCategoryAssociatedContent"; const BEFORE_UPDATECATEGORY_ASSOCIATED_CONTENT = "action.before_updateCategoryAssociatedContent"; const AFTER_UPDATECATEGORY_ASSOCIATED_CONTENT = "action.after_updateCategoryAssociatedContent"; @@ -191,6 +191,9 @@ final class TheliaEvents const PRODUCT_REMOVE_ACCESSORY = "action.productRemoveAccessory"; const PRODUCT_UPDATE_ACCESSORY_POSITION = "action.updateProductPosition"; + const PRODUCT_FEATURE_UPDATE_VALUE = "action.after_updateProductFeatureValue"; + const PRODUCT_FEATURE_DELETE_VALUE = "action.after_deleteProductFeatureValue"; + const BEFORE_CREATEPRODUCT = "action.before_createproduct"; const AFTER_CREATEPRODUCT = "action.after_createproduct"; @@ -211,17 +214,28 @@ final class TheliaEvents const BEFORE_UPDATEACCESSORY = "action.before_updateAccessory"; const AFTER_UPDATEACCESSORY = "action.after_updateAccessory"; - // -- Product Associated Content -------------------------------------------------- + // -- Product Associated Content ------------------------------------------- const BEFORE_CREATEPRODUCT_ASSOCIATED_CONTENT = "action.before_createProductAssociatedContent"; const AFTER_CREATEPRODUCT_ASSOCIATED_CONTENT = "action.after_createProductAssociatedContent"; - const BEFORE_DELETEPRODUCT_ASSOCIATED_CONTENT = "action.before_deleteProductAssociatedContenty"; - const AFTER_DELETEPRODUCT_ASSOCIATED_CONTENT = "action.after_deleteproduct_accessory"; + const BEFORE_DELETEPRODUCT_ASSOCIATED_CONTENT = "action.before_deleteProductAssociatedContent"; + const AFTER_DELETEPRODUCT_ASSOCIATED_CONTENT = "action.after_deleteProductAssociatedContent"; const BEFORE_UPDATEPRODUCT_ASSOCIATED_CONTENT = "action.before_updateProductAssociatedContent"; const AFTER_UPDATEPRODUCT_ASSOCIATED_CONTENT = "action.after_updateProductAssociatedContent"; + // -- Feature product ------------------------------------------------------ + + const BEFORE_CREATEFEATURE_PRODUCT = "action.before_createFeatureProduct"; + const AFTER_CREATEFEATURE_PRODUCT = "action.after_createFeatureProduct"; + + const BEFORE_DELETEFEATURE_PRODUCT = "action.before_deleteFeatureProduct"; + const AFTER_DELETEFEATURE_PRODUCT = "action.after_deleteFeatureProduct"; + + const BEFORE_UPDATEFEATURE_PRODUCT = "action.before_updateFeatureProduct"; + const AFTER_UPDATEFEATURE_PRODUCT = "action.after_updateFeatureProduct"; + /** * sent when a new existing cat id duplicated. This append when current customer is different from current cart */ diff --git a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php index 30a8dcf27..eaa81153b 100755 --- a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php +++ b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php @@ -59,7 +59,7 @@ class FeatureValue extends BaseI18nLoop Argument::createIntTypeArgument('product', null, true), Argument::createIntListTypeArgument('feature_availability'), Argument::createBooleanTypeArgument('exclude_feature_availability', 0), - Argument::createBooleanTypeArgument('exclude_personal_values', 0), + Argument::createBooleanTypeArgument('exclude_free_text', 0), new Argument( 'order', new TypeCollection( @@ -79,14 +79,14 @@ class FeatureValue extends BaseI18nLoop { $search = FeatureProductQuery::create(); - /* manage featureAv translations */ - $locale = $this->configureI18nProcessing( - $search, - array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), - FeatureAvTableMap::TABLE_NAME, - 'FEATURE_AV_ID', - true - ); + // manage featureAv translations + $locale = $this->configureI18nProcessing( + $search, + array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), + FeatureAvTableMap::TABLE_NAME, + 'FEATURE_AV_ID', + true + ); $feature = $this->getFeature(); @@ -103,13 +103,9 @@ class FeatureValue extends BaseI18nLoop } $excludeFeatureAvailability = $this->getExclude_feature_availability(); - if ($excludeFeatureAvailability == true) { - $search->filterByFeatureAvId(null, Criteria::NULL); - } - $excludeDefaultValues = $this->getExclude_personal_values(); - if ($excludeDefaultValues == true) { - $search->filterByByDefault(null, Criteria::NULL); + if ($excludeFeatureAvailability == true) { + $search->filterByFeatureAvId(null, Criteria::ISNULL); } $orders = $this->getOrder(); @@ -137,16 +133,24 @@ class FeatureValue extends BaseI18nLoop foreach ($featureValues as $featureValue) { $loopResultRow = new LoopResultRow($loopResult, $featureValue, $this->versionable, $this->timestampable, $this->countable); - $loopResultRow->set("ID", $featureValue->getId()); $loopResultRow - ->set("LOCALE",$locale) - ->set("PERSONAL_VALUE", $featureValue->getByDefault()) - ->set("TITLE",$featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_TITLE')) - ->set("CHAPO", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_CHAPO')) - ->set("DESCRIPTION", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_DESCRIPTION')) - ->set("POSTSCRIPTUM", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_POSTSCRIPTUM')) - ->set("POSITION", $featureValue->getPosition()); + ->set("ID" , $featureValue->getId()) + ->set("PRODUCT" , $featureValue->getProductId()) + ->set("FEATURE_AV_ID" , $featureValue->getFeatureAvId()) + ->set("FREE_TEXT_VALUE" , $featureValue->getFreeTextValue()) + + ->set("IS_FREE_TEXT" , is_null($featureValue->getFeatureAvId()) ? 1 : 0) + ->set("IS_FEATURE_AV" , is_null($featureValue->getFeatureAvId()) ? 0 : 1) + + ->set("LOCALE" , $locale) + ->set("TITLE" , $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_TITLE')) + ->set("CHAPO" , $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_CHAPO')) + ->set("DESCRIPTION" , $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_DESCRIPTION')) + ->set("POSTSCRIPTUM" , $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_POSTSCRIPTUM')) + + ->set("POSITION" , $featureValue->getPosition()) + ; $loopResult->addRow($loopResultRow); } diff --git a/core/lib/Thelia/Core/Template/Loop/Product.php b/core/lib/Thelia/Core/Template/Loop/Product.php index 9deade5cc..7c812d81f 100755 --- a/core/lib/Thelia/Core/Template/Loop/Product.php +++ b/core/lib/Thelia/Core/Template/Loop/Product.php @@ -650,6 +650,7 @@ class Product extends BaseI18nLoop ->set("IS_NEW" , $product->getVirtualColumn('main_product_is_new')) ->set("POSITION" , $product->getPosition()) ->set("VISIBLE" , $product->getVisible() ? "1" : "0") + ->set("TEMPLATE" , $product->getTemplateId()) ->set("HAS_PREVIOUS" , $previous != null ? 1 : 0) ->set("HAS_NEXT" , $next != null ? 1 : 0) ->set("PREVIOUS" , $previous != null ? $previous->getId() : -1) diff --git a/core/lib/Thelia/Model/Base/AttributeCombination.php b/core/lib/Thelia/Model/Base/AttributeCombination.php index ef840a5a1..14868edf7 100644 --- a/core/lib/Thelia/Model/Base/AttributeCombination.php +++ b/core/lib/Thelia/Model/Base/AttributeCombination.php @@ -78,6 +78,13 @@ abstract class AttributeCombination implements ActiveRecordInterface */ protected $product_sale_elements_id; + /** + * The value for the is_default field. + * Note: this column has a database default value of: false + * @var boolean + */ + protected $is_default; + /** * The value for the created_at field. * @var string @@ -113,11 +120,24 @@ abstract class AttributeCombination implements ActiveRecordInterface */ protected $alreadyInSave = false; + /** + * 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->is_default = false; + } + /** * Initializes internal state of Thelia\Model\Base\AttributeCombination object. + * @see applyDefaults() */ public function __construct() { + $this->applyDefaultValues(); } /** @@ -400,6 +420,17 @@ abstract class AttributeCombination implements ActiveRecordInterface return $this->product_sale_elements_id; } + /** + * Get the [is_default] column value. + * + * @return boolean + */ + public function getIsDefault() + { + + return $this->is_default; + } + /** * Get the [optionally formatted] temporal [created_at] column value. * @@ -515,6 +546,35 @@ abstract class AttributeCombination implements ActiveRecordInterface return $this; } // setProductSaleElementsId() + /** + * Sets the value of the [is_default] column. + * Non-boolean arguments are converted using the following rules: + * * 1, '1', 'true', 'on', and 'yes' are converted to boolean true + * * 0, '0', 'false', 'off', and 'no' are converted to boolean false + * Check on string values is case insensitive (so 'FaLsE' is seen as 'false'). + * + * @param boolean|integer|string $v The new value + * @return \Thelia\Model\AttributeCombination The current object (for fluent API support) + */ + public function setIsDefault($v) + { + if ($v !== null) { + if (is_string($v)) { + $v = in_array(strtolower($v), array('false', 'off', '-', 'no', 'n', '0', '')) ? false : true; + } else { + $v = (boolean) $v; + } + } + + if ($this->is_default !== $v) { + $this->is_default = $v; + $this->modifiedColumns[] = AttributeCombinationTableMap::IS_DEFAULT; + } + + + return $this; + } // setIsDefault() + /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * @@ -567,6 +627,10 @@ abstract class AttributeCombination implements ActiveRecordInterface */ public function hasOnlyDefaultValues() { + if ($this->is_default !== false) { + return false; + } + // otherwise, everything was equal, so return TRUE return true; } // hasOnlyDefaultValues() @@ -603,13 +667,16 @@ abstract class AttributeCombination implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : AttributeCombinationTableMap::translateFieldName('ProductSaleElementsId', TableMap::TYPE_PHPNAME, $indexType)]; $this->product_sale_elements_id = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : AttributeCombinationTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : AttributeCombinationTableMap::translateFieldName('IsDefault', TableMap::TYPE_PHPNAME, $indexType)]; + $this->is_default = (null !== $col) ? (boolean) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : AttributeCombinationTableMap::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 : AttributeCombinationTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : AttributeCombinationTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -622,7 +689,7 @@ abstract class AttributeCombination implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 5; // 5 = AttributeCombinationTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 6; // 6 = AttributeCombinationTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\AttributeCombination object", 0, $e); @@ -885,6 +952,9 @@ abstract class AttributeCombination implements ActiveRecordInterface if ($this->isColumnModified(AttributeCombinationTableMap::PRODUCT_SALE_ELEMENTS_ID)) { $modifiedColumns[':p' . $index++] = 'PRODUCT_SALE_ELEMENTS_ID'; } + if ($this->isColumnModified(AttributeCombinationTableMap::IS_DEFAULT)) { + $modifiedColumns[':p' . $index++] = 'IS_DEFAULT'; + } if ($this->isColumnModified(AttributeCombinationTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } @@ -911,6 +981,9 @@ abstract class AttributeCombination implements ActiveRecordInterface case 'PRODUCT_SALE_ELEMENTS_ID': $stmt->bindValue($identifier, $this->product_sale_elements_id, PDO::PARAM_INT); break; + case 'IS_DEFAULT': + $stmt->bindValue($identifier, (int) $this->is_default, 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; @@ -982,9 +1055,12 @@ abstract class AttributeCombination implements ActiveRecordInterface return $this->getProductSaleElementsId(); break; case 3: - return $this->getCreatedAt(); + return $this->getIsDefault(); break; case 4: + return $this->getCreatedAt(); + break; + case 5: return $this->getUpdatedAt(); break; default: @@ -1019,8 +1095,9 @@ abstract class AttributeCombination implements ActiveRecordInterface $keys[0] => $this->getAttributeId(), $keys[1] => $this->getAttributeAvId(), $keys[2] => $this->getProductSaleElementsId(), - $keys[3] => $this->getCreatedAt(), - $keys[4] => $this->getUpdatedAt(), + $keys[3] => $this->getIsDefault(), + $keys[4] => $this->getCreatedAt(), + $keys[5] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1082,9 +1159,12 @@ abstract class AttributeCombination implements ActiveRecordInterface $this->setProductSaleElementsId($value); break; case 3: - $this->setCreatedAt($value); + $this->setIsDefault($value); break; case 4: + $this->setCreatedAt($value); + break; + case 5: $this->setUpdatedAt($value); break; } // switch() @@ -1114,8 +1194,9 @@ abstract class AttributeCombination implements ActiveRecordInterface if (array_key_exists($keys[0], $arr)) $this->setAttributeId($arr[$keys[0]]); if (array_key_exists($keys[1], $arr)) $this->setAttributeAvId($arr[$keys[1]]); if (array_key_exists($keys[2], $arr)) $this->setProductSaleElementsId($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]]); + if (array_key_exists($keys[3], $arr)) $this->setIsDefault($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setCreatedAt($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setUpdatedAt($arr[$keys[5]]); } /** @@ -1130,6 +1211,7 @@ abstract class AttributeCombination implements ActiveRecordInterface if ($this->isColumnModified(AttributeCombinationTableMap::ATTRIBUTE_ID)) $criteria->add(AttributeCombinationTableMap::ATTRIBUTE_ID, $this->attribute_id); if ($this->isColumnModified(AttributeCombinationTableMap::ATTRIBUTE_AV_ID)) $criteria->add(AttributeCombinationTableMap::ATTRIBUTE_AV_ID, $this->attribute_av_id); if ($this->isColumnModified(AttributeCombinationTableMap::PRODUCT_SALE_ELEMENTS_ID)) $criteria->add(AttributeCombinationTableMap::PRODUCT_SALE_ELEMENTS_ID, $this->product_sale_elements_id); + if ($this->isColumnModified(AttributeCombinationTableMap::IS_DEFAULT)) $criteria->add(AttributeCombinationTableMap::IS_DEFAULT, $this->is_default); if ($this->isColumnModified(AttributeCombinationTableMap::CREATED_AT)) $criteria->add(AttributeCombinationTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(AttributeCombinationTableMap::UPDATED_AT)) $criteria->add(AttributeCombinationTableMap::UPDATED_AT, $this->updated_at); @@ -1208,6 +1290,7 @@ abstract class AttributeCombination implements ActiveRecordInterface $copyObj->setAttributeId($this->getAttributeId()); $copyObj->setAttributeAvId($this->getAttributeAvId()); $copyObj->setProductSaleElementsId($this->getProductSaleElementsId()); + $copyObj->setIsDefault($this->getIsDefault()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); if ($makeNew) { @@ -1398,10 +1481,12 @@ abstract class AttributeCombination implements ActiveRecordInterface $this->attribute_id = null; $this->attribute_av_id = null; $this->product_sale_elements_id = null; + $this->is_default = 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/AttributeCombinationQuery.php b/core/lib/Thelia/Model/Base/AttributeCombinationQuery.php index 291ff7725..e0f4ee0ea 100644 --- a/core/lib/Thelia/Model/Base/AttributeCombinationQuery.php +++ b/core/lib/Thelia/Model/Base/AttributeCombinationQuery.php @@ -24,12 +24,14 @@ use Thelia\Model\Map\AttributeCombinationTableMap; * @method ChildAttributeCombinationQuery orderByAttributeId($order = Criteria::ASC) Order by the attribute_id column * @method ChildAttributeCombinationQuery orderByAttributeAvId($order = Criteria::ASC) Order by the attribute_av_id column * @method ChildAttributeCombinationQuery orderByProductSaleElementsId($order = Criteria::ASC) Order by the product_sale_elements_id column + * @method ChildAttributeCombinationQuery orderByIsDefault($order = Criteria::ASC) Order by the is_default column * @method ChildAttributeCombinationQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildAttributeCombinationQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * * @method ChildAttributeCombinationQuery groupByAttributeId() Group by the attribute_id column * @method ChildAttributeCombinationQuery groupByAttributeAvId() Group by the attribute_av_id column * @method ChildAttributeCombinationQuery groupByProductSaleElementsId() Group by the product_sale_elements_id column + * @method ChildAttributeCombinationQuery groupByIsDefault() Group by the is_default column * @method ChildAttributeCombinationQuery groupByCreatedAt() Group by the created_at column * @method ChildAttributeCombinationQuery groupByUpdatedAt() Group by the updated_at column * @@ -55,12 +57,14 @@ use Thelia\Model\Map\AttributeCombinationTableMap; * @method ChildAttributeCombination findOneByAttributeId(int $attribute_id) Return the first ChildAttributeCombination filtered by the attribute_id column * @method ChildAttributeCombination findOneByAttributeAvId(int $attribute_av_id) Return the first ChildAttributeCombination filtered by the attribute_av_id column * @method ChildAttributeCombination findOneByProductSaleElementsId(int $product_sale_elements_id) Return the first ChildAttributeCombination filtered by the product_sale_elements_id column + * @method ChildAttributeCombination findOneByIsDefault(boolean $is_default) Return the first ChildAttributeCombination filtered by the is_default column * @method ChildAttributeCombination findOneByCreatedAt(string $created_at) Return the first ChildAttributeCombination filtered by the created_at column * @method ChildAttributeCombination findOneByUpdatedAt(string $updated_at) Return the first ChildAttributeCombination filtered by the updated_at column * * @method array findByAttributeId(int $attribute_id) Return ChildAttributeCombination objects filtered by the attribute_id column * @method array findByAttributeAvId(int $attribute_av_id) Return ChildAttributeCombination objects filtered by the attribute_av_id column * @method array findByProductSaleElementsId(int $product_sale_elements_id) Return ChildAttributeCombination objects filtered by the product_sale_elements_id column + * @method array findByIsDefault(boolean $is_default) Return ChildAttributeCombination objects filtered by the is_default column * @method array findByCreatedAt(string $created_at) Return ChildAttributeCombination objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildAttributeCombination objects filtered by the updated_at column * @@ -151,7 +155,7 @@ abstract class AttributeCombinationQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ATTRIBUTE_ID, ATTRIBUTE_AV_ID, PRODUCT_SALE_ELEMENTS_ID, CREATED_AT, UPDATED_AT FROM attribute_combination WHERE ATTRIBUTE_ID = :p0 AND ATTRIBUTE_AV_ID = :p1 AND PRODUCT_SALE_ELEMENTS_ID = :p2'; + $sql = 'SELECT ATTRIBUTE_ID, ATTRIBUTE_AV_ID, PRODUCT_SALE_ELEMENTS_ID, IS_DEFAULT, CREATED_AT, UPDATED_AT FROM attribute_combination WHERE ATTRIBUTE_ID = :p0 AND ATTRIBUTE_AV_ID = :p1 AND PRODUCT_SALE_ELEMENTS_ID = :p2'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key[0], PDO::PARAM_INT); @@ -385,6 +389,33 @@ abstract class AttributeCombinationQuery extends ModelCriteria return $this->addUsingAlias(AttributeCombinationTableMap::PRODUCT_SALE_ELEMENTS_ID, $productSaleElementsId, $comparison); } + /** + * Filter the query on the is_default column + * + * Example usage: + * + * $query->filterByIsDefault(true); // WHERE is_default = true + * $query->filterByIsDefault('yes'); // WHERE is_default = true + * + * + * @param boolean|string $isDefault The value to use as filter. + * Non-boolean arguments are converted using the following rules: + * * 1, '1', 'true', 'on', and 'yes' are converted to boolean true + * * 0, '0', 'false', 'off', and 'no' are converted to boolean false + * Check on string values is case insensitive (so 'FaLsE' is seen as 'false'). + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByIsDefault($isDefault = null, $comparison = null) + { + if (is_string($isDefault)) { + $is_default = in_array(strtolower($isDefault), array('false', 'off', '-', 'no', 'n', '0', '')) ? false : true; + } + + return $this->addUsingAlias(AttributeCombinationTableMap::IS_DEFAULT, $isDefault, $comparison); + } + /** * Filter the query on the created_at column * diff --git a/core/lib/Thelia/Model/Base/FeatureProduct.php b/core/lib/Thelia/Model/Base/FeatureProduct.php index 4af200d51..039967cee 100644 --- a/core/lib/Thelia/Model/Base/FeatureProduct.php +++ b/core/lib/Thelia/Model/Base/FeatureProduct.php @@ -85,10 +85,10 @@ abstract class FeatureProduct implements ActiveRecordInterface protected $feature_av_id; /** - * The value for the by_default field. + * The value for the free_text_value field. * @var string */ - protected $by_default; + protected $free_text_value; /** * The value for the position field. @@ -430,14 +430,14 @@ abstract class FeatureProduct implements ActiveRecordInterface } /** - * Get the [by_default] column value. + * Get the [free_text_value] column value. * * @return string */ - public function getByDefault() + public function getFreeTextValue() { - return $this->by_default; + return $this->free_text_value; } /** @@ -588,25 +588,25 @@ abstract class FeatureProduct implements ActiveRecordInterface } // setFeatureAvId() /** - * Set the value of [by_default] column. + * Set the value of [free_text_value] column. * * @param string $v new value * @return \Thelia\Model\FeatureProduct The current object (for fluent API support) */ - public function setByDefault($v) + public function setFreeTextValue($v) { if ($v !== null) { $v = (string) $v; } - if ($this->by_default !== $v) { - $this->by_default = $v; - $this->modifiedColumns[] = FeatureProductTableMap::BY_DEFAULT; + if ($this->free_text_value !== $v) { + $this->free_text_value = $v; + $this->modifiedColumns[] = FeatureProductTableMap::FREE_TEXT_VALUE; } return $this; - } // setByDefault() + } // setFreeTextValue() /** * Set the value of [position] column. @@ -720,8 +720,8 @@ abstract class FeatureProduct implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : FeatureProductTableMap::translateFieldName('FeatureAvId', TableMap::TYPE_PHPNAME, $indexType)]; $this->feature_av_id = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : FeatureProductTableMap::translateFieldName('ByDefault', TableMap::TYPE_PHPNAME, $indexType)]; - $this->by_default = (null !== $col) ? (string) $col : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : FeatureProductTableMap::translateFieldName('FreeTextValue', TableMap::TYPE_PHPNAME, $indexType)]; + $this->free_text_value = (null !== $col) ? (string) $col : null; $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : FeatureProductTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)]; $this->position = (null !== $col) ? (int) $col : null; @@ -1015,8 +1015,8 @@ abstract class FeatureProduct implements ActiveRecordInterface if ($this->isColumnModified(FeatureProductTableMap::FEATURE_AV_ID)) { $modifiedColumns[':p' . $index++] = 'FEATURE_AV_ID'; } - if ($this->isColumnModified(FeatureProductTableMap::BY_DEFAULT)) { - $modifiedColumns[':p' . $index++] = 'BY_DEFAULT'; + if ($this->isColumnModified(FeatureProductTableMap::FREE_TEXT_VALUE)) { + $modifiedColumns[':p' . $index++] = 'FREE_TEXT_VALUE'; } if ($this->isColumnModified(FeatureProductTableMap::POSITION)) { $modifiedColumns[':p' . $index++] = 'POSITION'; @@ -1050,8 +1050,8 @@ abstract class FeatureProduct implements ActiveRecordInterface case 'FEATURE_AV_ID': $stmt->bindValue($identifier, $this->feature_av_id, PDO::PARAM_INT); break; - case 'BY_DEFAULT': - $stmt->bindValue($identifier, $this->by_default, PDO::PARAM_STR); + case 'FREE_TEXT_VALUE': + $stmt->bindValue($identifier, $this->free_text_value, PDO::PARAM_STR); break; case 'POSITION': $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT); @@ -1137,7 +1137,7 @@ abstract class FeatureProduct implements ActiveRecordInterface return $this->getFeatureAvId(); break; case 4: - return $this->getByDefault(); + return $this->getFreeTextValue(); break; case 5: return $this->getPosition(); @@ -1181,7 +1181,7 @@ abstract class FeatureProduct implements ActiveRecordInterface $keys[1] => $this->getProductId(), $keys[2] => $this->getFeatureId(), $keys[3] => $this->getFeatureAvId(), - $keys[4] => $this->getByDefault(), + $keys[4] => $this->getFreeTextValue(), $keys[5] => $this->getPosition(), $keys[6] => $this->getCreatedAt(), $keys[7] => $this->getUpdatedAt(), @@ -1249,7 +1249,7 @@ abstract class FeatureProduct implements ActiveRecordInterface $this->setFeatureAvId($value); break; case 4: - $this->setByDefault($value); + $this->setFreeTextValue($value); break; case 5: $this->setPosition($value); @@ -1288,7 +1288,7 @@ abstract class FeatureProduct implements ActiveRecordInterface if (array_key_exists($keys[1], $arr)) $this->setProductId($arr[$keys[1]]); if (array_key_exists($keys[2], $arr)) $this->setFeatureId($arr[$keys[2]]); if (array_key_exists($keys[3], $arr)) $this->setFeatureAvId($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setByDefault($arr[$keys[4]]); + if (array_key_exists($keys[4], $arr)) $this->setFreeTextValue($arr[$keys[4]]); if (array_key_exists($keys[5], $arr)) $this->setPosition($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]]); @@ -1307,7 +1307,7 @@ abstract class FeatureProduct implements ActiveRecordInterface if ($this->isColumnModified(FeatureProductTableMap::PRODUCT_ID)) $criteria->add(FeatureProductTableMap::PRODUCT_ID, $this->product_id); if ($this->isColumnModified(FeatureProductTableMap::FEATURE_ID)) $criteria->add(FeatureProductTableMap::FEATURE_ID, $this->feature_id); if ($this->isColumnModified(FeatureProductTableMap::FEATURE_AV_ID)) $criteria->add(FeatureProductTableMap::FEATURE_AV_ID, $this->feature_av_id); - if ($this->isColumnModified(FeatureProductTableMap::BY_DEFAULT)) $criteria->add(FeatureProductTableMap::BY_DEFAULT, $this->by_default); + if ($this->isColumnModified(FeatureProductTableMap::FREE_TEXT_VALUE)) $criteria->add(FeatureProductTableMap::FREE_TEXT_VALUE, $this->free_text_value); if ($this->isColumnModified(FeatureProductTableMap::POSITION)) $criteria->add(FeatureProductTableMap::POSITION, $this->position); if ($this->isColumnModified(FeatureProductTableMap::CREATED_AT)) $criteria->add(FeatureProductTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(FeatureProductTableMap::UPDATED_AT)) $criteria->add(FeatureProductTableMap::UPDATED_AT, $this->updated_at); @@ -1377,7 +1377,7 @@ abstract class FeatureProduct implements ActiveRecordInterface $copyObj->setProductId($this->getProductId()); $copyObj->setFeatureId($this->getFeatureId()); $copyObj->setFeatureAvId($this->getFeatureAvId()); - $copyObj->setByDefault($this->getByDefault()); + $copyObj->setFreeTextValue($this->getFreeTextValue()); $copyObj->setPosition($this->getPosition()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -1571,7 +1571,7 @@ abstract class FeatureProduct implements ActiveRecordInterface $this->product_id = null; $this->feature_id = null; $this->feature_av_id = null; - $this->by_default = null; + $this->free_text_value = null; $this->position = null; $this->created_at = null; $this->updated_at = null; diff --git a/core/lib/Thelia/Model/Base/FeatureProductQuery.php b/core/lib/Thelia/Model/Base/FeatureProductQuery.php index c6a8f2a73..eb2ee7ec1 100644 --- a/core/lib/Thelia/Model/Base/FeatureProductQuery.php +++ b/core/lib/Thelia/Model/Base/FeatureProductQuery.php @@ -25,7 +25,7 @@ use Thelia\Model\Map\FeatureProductTableMap; * @method ChildFeatureProductQuery orderByProductId($order = Criteria::ASC) Order by the product_id column * @method ChildFeatureProductQuery orderByFeatureId($order = Criteria::ASC) Order by the feature_id column * @method ChildFeatureProductQuery orderByFeatureAvId($order = Criteria::ASC) Order by the feature_av_id column - * @method ChildFeatureProductQuery orderByByDefault($order = Criteria::ASC) Order by the by_default column + * @method ChildFeatureProductQuery orderByFreeTextValue($order = Criteria::ASC) Order by the free_text_value column * @method ChildFeatureProductQuery orderByPosition($order = Criteria::ASC) Order by the position column * @method ChildFeatureProductQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildFeatureProductQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column @@ -34,7 +34,7 @@ use Thelia\Model\Map\FeatureProductTableMap; * @method ChildFeatureProductQuery groupByProductId() Group by the product_id column * @method ChildFeatureProductQuery groupByFeatureId() Group by the feature_id column * @method ChildFeatureProductQuery groupByFeatureAvId() Group by the feature_av_id column - * @method ChildFeatureProductQuery groupByByDefault() Group by the by_default column + * @method ChildFeatureProductQuery groupByFreeTextValue() Group by the free_text_value column * @method ChildFeatureProductQuery groupByPosition() Group by the position column * @method ChildFeatureProductQuery groupByCreatedAt() Group by the created_at column * @method ChildFeatureProductQuery groupByUpdatedAt() Group by the updated_at column @@ -62,7 +62,7 @@ use Thelia\Model\Map\FeatureProductTableMap; * @method ChildFeatureProduct findOneByProductId(int $product_id) Return the first ChildFeatureProduct filtered by the product_id column * @method ChildFeatureProduct findOneByFeatureId(int $feature_id) Return the first ChildFeatureProduct filtered by the feature_id column * @method ChildFeatureProduct findOneByFeatureAvId(int $feature_av_id) Return the first ChildFeatureProduct filtered by the feature_av_id column - * @method ChildFeatureProduct findOneByByDefault(string $by_default) Return the first ChildFeatureProduct filtered by the by_default column + * @method ChildFeatureProduct findOneByFreeTextValue(string $free_text_value) Return the first ChildFeatureProduct filtered by the free_text_value column * @method ChildFeatureProduct findOneByPosition(int $position) Return the first ChildFeatureProduct filtered by the position column * @method ChildFeatureProduct findOneByCreatedAt(string $created_at) Return the first ChildFeatureProduct filtered by the created_at column * @method ChildFeatureProduct findOneByUpdatedAt(string $updated_at) Return the first ChildFeatureProduct filtered by the updated_at column @@ -71,7 +71,7 @@ use Thelia\Model\Map\FeatureProductTableMap; * @method array findByProductId(int $product_id) Return ChildFeatureProduct objects filtered by the product_id column * @method array findByFeatureId(int $feature_id) Return ChildFeatureProduct objects filtered by the feature_id column * @method array findByFeatureAvId(int $feature_av_id) Return ChildFeatureProduct objects filtered by the feature_av_id column - * @method array findByByDefault(string $by_default) Return ChildFeatureProduct objects filtered by the by_default column + * @method array findByFreeTextValue(string $free_text_value) Return ChildFeatureProduct objects filtered by the free_text_value column * @method array findByPosition(int $position) Return ChildFeatureProduct objects filtered by the position column * @method array findByCreatedAt(string $created_at) Return ChildFeatureProduct objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildFeatureProduct objects filtered by the updated_at column @@ -163,7 +163,7 @@ abstract class FeatureProductQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, PRODUCT_ID, FEATURE_ID, FEATURE_AV_ID, BY_DEFAULT, POSITION, CREATED_AT, UPDATED_AT FROM feature_product WHERE ID = :p0'; + $sql = 'SELECT ID, PRODUCT_ID, FEATURE_ID, FEATURE_AV_ID, FREE_TEXT_VALUE, POSITION, CREATED_AT, UPDATED_AT FROM feature_product WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -423,32 +423,32 @@ abstract class FeatureProductQuery extends ModelCriteria } /** - * Filter the query on the by_default column + * Filter the query on the free_text_value column * * Example usage: * - * $query->filterByByDefault('fooValue'); // WHERE by_default = 'fooValue' - * $query->filterByByDefault('%fooValue%'); // WHERE by_default LIKE '%fooValue%' + * $query->filterByFreeTextValue('fooValue'); // WHERE free_text_value = 'fooValue' + * $query->filterByFreeTextValue('%fooValue%'); // WHERE free_text_value LIKE '%fooValue%' * * - * @param string $byDefault The value to use as filter. + * @param string $freeTextValue 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 ChildFeatureProductQuery The current query, for fluid interface */ - public function filterByByDefault($byDefault = null, $comparison = null) + public function filterByFreeTextValue($freeTextValue = null, $comparison = null) { if (null === $comparison) { - if (is_array($byDefault)) { + if (is_array($freeTextValue)) { $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $byDefault)) { - $byDefault = str_replace('*', '%', $byDefault); + } elseif (preg_match('/[\%\*]/', $freeTextValue)) { + $freeTextValue = str_replace('*', '%', $freeTextValue); $comparison = Criteria::LIKE; } } - return $this->addUsingAlias(FeatureProductTableMap::BY_DEFAULT, $byDefault, $comparison); + return $this->addUsingAlias(FeatureProductTableMap::FREE_TEXT_VALUE, $freeTextValue, $comparison); } /** diff --git a/core/lib/Thelia/Model/Base/OrderProduct.php b/core/lib/Thelia/Model/Base/OrderProduct.php index 2bf9c7ace..6ff03d427 100644 --- a/core/lib/Thelia/Model/Base/OrderProduct.php +++ b/core/lib/Thelia/Model/Base/OrderProduct.php @@ -18,10 +18,12 @@ use Propel\Runtime\Map\TableMap; use Propel\Runtime\Parser\AbstractParser; use Propel\Runtime\Util\PropelDateTime; use Thelia\Model\Order as ChildOrder; -use Thelia\Model\OrderFeature as ChildOrderFeature; -use Thelia\Model\OrderFeatureQuery as ChildOrderFeatureQuery; use Thelia\Model\OrderProduct as ChildOrderProduct; +use Thelia\Model\OrderProductAttributeCombination as ChildOrderProductAttributeCombination; +use Thelia\Model\OrderProductAttributeCombinationQuery as ChildOrderProductAttributeCombinationQuery; use Thelia\Model\OrderProductQuery as ChildOrderProductQuery; +use Thelia\Model\OrderProductTax as ChildOrderProductTax; +use Thelia\Model\OrderProductTaxQuery as ChildOrderProductTaxQuery; use Thelia\Model\OrderQuery as ChildOrderQuery; use Thelia\Model\Map\OrderProductTableMap; @@ -77,12 +79,24 @@ abstract class OrderProduct implements ActiveRecordInterface */ protected $product_ref; + /** + * The value for the product_sale_elements_ref field. + * @var string + */ + protected $product_sale_elements_ref; + /** * The value for the title field. * @var string */ protected $title; + /** + * The value for the chapo field. + * @var string + */ + protected $chapo; + /** * The value for the description field. * @var string @@ -90,10 +104,10 @@ abstract class OrderProduct implements ActiveRecordInterface protected $description; /** - * The value for the chapo field. + * The value for the postscriptum field. * @var string */ - protected $chapo; + protected $postscriptum; /** * The value for the quantity field. @@ -108,10 +122,40 @@ abstract class OrderProduct implements ActiveRecordInterface protected $price; /** - * The value for the tax field. - * @var double + * The value for the promo_price field. + * @var string */ - protected $tax; + protected $promo_price; + + /** + * The value for the was_new field. + * @var int + */ + protected $was_new; + + /** + * The value for the was_in_promo field. + * @var int + */ + protected $was_in_promo; + + /** + * The value for the weight field. + * @var string + */ + protected $weight; + + /** + * The value for the tax_rule_title field. + * @var string + */ + protected $tax_rule_title; + + /** + * The value for the tax_rule_description field. + * @var string + */ + protected $tax_rule_description; /** * The value for the parent field. @@ -137,10 +181,16 @@ abstract class OrderProduct implements ActiveRecordInterface protected $aOrder; /** - * @var ObjectCollection|ChildOrderFeature[] Collection to store aggregation of ChildOrderFeature objects. + * @var ObjectCollection|ChildOrderProductAttributeCombination[] Collection to store aggregation of ChildOrderProductAttributeCombination objects. */ - protected $collOrderFeatures; - protected $collOrderFeaturesPartial; + protected $collOrderProductAttributeCombinations; + protected $collOrderProductAttributeCombinationsPartial; + + /** + * @var ObjectCollection|ChildOrderProductTax[] Collection to store aggregation of ChildOrderProductTax objects. + */ + protected $collOrderProductTaxes; + protected $collOrderProductTaxesPartial; /** * Flag to prevent endless save loop, if this object is referenced @@ -154,7 +204,13 @@ abstract class OrderProduct implements ActiveRecordInterface * An array of objects scheduled for deletion. * @var ObjectCollection */ - protected $orderFeaturesScheduledForDeletion = null; + protected $orderProductAttributeCombinationsScheduledForDeletion = null; + + /** + * An array of objects scheduled for deletion. + * @var ObjectCollection + */ + protected $orderProductTaxesScheduledForDeletion = null; /** * Initializes internal state of Thelia\Model\Base\OrderProduct object. @@ -443,6 +499,17 @@ abstract class OrderProduct implements ActiveRecordInterface return $this->product_ref; } + /** + * Get the [product_sale_elements_ref] column value. + * + * @return string + */ + public function getProductSaleElementsRef() + { + + return $this->product_sale_elements_ref; + } + /** * Get the [title] column value. * @@ -454,6 +521,17 @@ abstract class OrderProduct implements ActiveRecordInterface return $this->title; } + /** + * Get the [chapo] column value. + * + * @return string + */ + public function getChapo() + { + + return $this->chapo; + } + /** * Get the [description] column value. * @@ -466,14 +544,14 @@ abstract class OrderProduct implements ActiveRecordInterface } /** - * Get the [chapo] column value. + * Get the [postscriptum] column value. * * @return string */ - public function getChapo() + public function getPostscriptum() { - return $this->chapo; + return $this->postscriptum; } /** @@ -499,19 +577,74 @@ abstract class OrderProduct implements ActiveRecordInterface } /** - * Get the [tax] column value. + * Get the [promo_price] column value. * - * @return double + * @return string */ - public function getTax() + public function getPromoPrice() { - return $this->tax; + return $this->promo_price; + } + + /** + * Get the [was_new] column value. + * + * @return int + */ + public function getWasNew() + { + + return $this->was_new; + } + + /** + * Get the [was_in_promo] column value. + * + * @return int + */ + public function getWasInPromo() + { + + return $this->was_in_promo; + } + + /** + * Get the [weight] column value. + * + * @return string + */ + public function getWeight() + { + + return $this->weight; + } + + /** + * Get the [tax_rule_title] column value. + * + * @return string + */ + public function getTaxRuleTitle() + { + + return $this->tax_rule_title; + } + + /** + * Get the [tax_rule_description] column value. + * + * @return string + */ + public function getTaxRuleDescription() + { + + return $this->tax_rule_description; } /** * Get the [parent] column value. - * + * not managed yet * @return int */ public function getParent() @@ -627,6 +760,27 @@ abstract class OrderProduct implements ActiveRecordInterface return $this; } // setProductRef() + /** + * Set the value of [product_sale_elements_ref] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function setProductSaleElementsRef($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->product_sale_elements_ref !== $v) { + $this->product_sale_elements_ref = $v; + $this->modifiedColumns[] = OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF; + } + + + return $this; + } // setProductSaleElementsRef() + /** * Set the value of [title] column. * @@ -648,6 +802,27 @@ abstract class OrderProduct implements ActiveRecordInterface return $this; } // setTitle() + /** + * Set the value of [chapo] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function setChapo($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->chapo !== $v) { + $this->chapo = $v; + $this->modifiedColumns[] = OrderProductTableMap::CHAPO; + } + + + return $this; + } // setChapo() + /** * Set the value of [description] column. * @@ -670,25 +845,25 @@ abstract class OrderProduct implements ActiveRecordInterface } // setDescription() /** - * Set the value of [chapo] column. + * Set the value of [postscriptum] column. * * @param string $v new value * @return \Thelia\Model\OrderProduct The current object (for fluent API support) */ - public function setChapo($v) + public function setPostscriptum($v) { if ($v !== null) { $v = (string) $v; } - if ($this->chapo !== $v) { - $this->chapo = $v; - $this->modifiedColumns[] = OrderProductTableMap::CHAPO; + if ($this->postscriptum !== $v) { + $this->postscriptum = $v; + $this->modifiedColumns[] = OrderProductTableMap::POSTSCRIPTUM; } return $this; - } // setChapo() + } // setPostscriptum() /** * Set the value of [quantity] column. @@ -733,29 +908,134 @@ abstract class OrderProduct implements ActiveRecordInterface } // setPrice() /** - * Set the value of [tax] column. + * Set the value of [promo_price] column. * - * @param double $v new value + * @param string $v new value * @return \Thelia\Model\OrderProduct The current object (for fluent API support) */ - public function setTax($v) + public function setPromoPrice($v) { if ($v !== null) { - $v = (double) $v; + $v = (string) $v; } - if ($this->tax !== $v) { - $this->tax = $v; - $this->modifiedColumns[] = OrderProductTableMap::TAX; + if ($this->promo_price !== $v) { + $this->promo_price = $v; + $this->modifiedColumns[] = OrderProductTableMap::PROMO_PRICE; } return $this; - } // setTax() + } // setPromoPrice() + + /** + * Set the value of [was_new] column. + * + * @param int $v new value + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function setWasNew($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->was_new !== $v) { + $this->was_new = $v; + $this->modifiedColumns[] = OrderProductTableMap::WAS_NEW; + } + + + return $this; + } // setWasNew() + + /** + * Set the value of [was_in_promo] column. + * + * @param int $v new value + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function setWasInPromo($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->was_in_promo !== $v) { + $this->was_in_promo = $v; + $this->modifiedColumns[] = OrderProductTableMap::WAS_IN_PROMO; + } + + + return $this; + } // setWasInPromo() + + /** + * Set the value of [weight] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function setWeight($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->weight !== $v) { + $this->weight = $v; + $this->modifiedColumns[] = OrderProductTableMap::WEIGHT; + } + + + return $this; + } // setWeight() + + /** + * Set the value of [tax_rule_title] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function setTaxRuleTitle($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->tax_rule_title !== $v) { + $this->tax_rule_title = $v; + $this->modifiedColumns[] = OrderProductTableMap::TAX_RULE_TITLE; + } + + + return $this; + } // setTaxRuleTitle() + + /** + * Set the value of [tax_rule_description] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function setTaxRuleDescription($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->tax_rule_description !== $v) { + $this->tax_rule_description = $v; + $this->modifiedColumns[] = OrderProductTableMap::TAX_RULE_DESCRIPTION; + } + + + return $this; + } // setTaxRuleDescription() /** * Set the value of [parent] column. - * + * not managed yet * @param int $v new value * @return \Thelia\Model\OrderProduct The current object (for fluent API support) */ @@ -862,34 +1142,55 @@ abstract class OrderProduct implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : OrderProductTableMap::translateFieldName('ProductRef', TableMap::TYPE_PHPNAME, $indexType)]; $this->product_ref = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : OrderProductTableMap::translateFieldName('Title', TableMap::TYPE_PHPNAME, $indexType)]; - $this->title = (null !== $col) ? (string) $col : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : OrderProductTableMap::translateFieldName('ProductSaleElementsRef', TableMap::TYPE_PHPNAME, $indexType)]; + $this->product_sale_elements_ref = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : OrderProductTableMap::translateFieldName('Description', TableMap::TYPE_PHPNAME, $indexType)]; - $this->description = (null !== $col) ? (string) $col : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : OrderProductTableMap::translateFieldName('Title', TableMap::TYPE_PHPNAME, $indexType)]; + $this->title = (null !== $col) ? (string) $col : null; $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : OrderProductTableMap::translateFieldName('Chapo', TableMap::TYPE_PHPNAME, $indexType)]; $this->chapo = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : OrderProductTableMap::translateFieldName('Quantity', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : OrderProductTableMap::translateFieldName('Description', TableMap::TYPE_PHPNAME, $indexType)]; + $this->description = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : OrderProductTableMap::translateFieldName('Postscriptum', TableMap::TYPE_PHPNAME, $indexType)]; + $this->postscriptum = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : OrderProductTableMap::translateFieldName('Quantity', TableMap::TYPE_PHPNAME, $indexType)]; $this->quantity = (null !== $col) ? (double) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : OrderProductTableMap::translateFieldName('Price', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : OrderProductTableMap::translateFieldName('Price', TableMap::TYPE_PHPNAME, $indexType)]; $this->price = (null !== $col) ? (double) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : OrderProductTableMap::translateFieldName('Tax', TableMap::TYPE_PHPNAME, $indexType)]; - $this->tax = (null !== $col) ? (double) $col : null; + $col = $row[TableMap::TYPE_NUM == $indexType ? 10 + $startcol : OrderProductTableMap::translateFieldName('PromoPrice', TableMap::TYPE_PHPNAME, $indexType)]; + $this->promo_price = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : OrderProductTableMap::translateFieldName('Parent', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 11 + $startcol : OrderProductTableMap::translateFieldName('WasNew', TableMap::TYPE_PHPNAME, $indexType)]; + $this->was_new = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 12 + $startcol : OrderProductTableMap::translateFieldName('WasInPromo', TableMap::TYPE_PHPNAME, $indexType)]; + $this->was_in_promo = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 13 + $startcol : OrderProductTableMap::translateFieldName('Weight', TableMap::TYPE_PHPNAME, $indexType)]; + $this->weight = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 14 + $startcol : OrderProductTableMap::translateFieldName('TaxRuleTitle', TableMap::TYPE_PHPNAME, $indexType)]; + $this->tax_rule_title = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 15 + $startcol : OrderProductTableMap::translateFieldName('TaxRuleDescription', TableMap::TYPE_PHPNAME, $indexType)]; + $this->tax_rule_description = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 16 + $startcol : OrderProductTableMap::translateFieldName('Parent', TableMap::TYPE_PHPNAME, $indexType)]; $this->parent = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 10 + $startcol : OrderProductTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 17 + $startcol : OrderProductTableMap::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 ? 11 + $startcol : OrderProductTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 18 + $startcol : OrderProductTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -902,7 +1203,7 @@ abstract class OrderProduct implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 12; // 12 = OrderProductTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 19; // 19 = OrderProductTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\OrderProduct object", 0, $e); @@ -967,7 +1268,9 @@ abstract class OrderProduct implements ActiveRecordInterface if ($deep) { // also de-associate any related objects? $this->aOrder = null; - $this->collOrderFeatures = null; + $this->collOrderProductAttributeCombinations = null; + + $this->collOrderProductTaxes = null; } // if (deep) } @@ -1114,17 +1417,34 @@ abstract class OrderProduct implements ActiveRecordInterface $this->resetModified(); } - if ($this->orderFeaturesScheduledForDeletion !== null) { - if (!$this->orderFeaturesScheduledForDeletion->isEmpty()) { - \Thelia\Model\OrderFeatureQuery::create() - ->filterByPrimaryKeys($this->orderFeaturesScheduledForDeletion->getPrimaryKeys(false)) + if ($this->orderProductAttributeCombinationsScheduledForDeletion !== null) { + if (!$this->orderProductAttributeCombinationsScheduledForDeletion->isEmpty()) { + \Thelia\Model\OrderProductAttributeCombinationQuery::create() + ->filterByPrimaryKeys($this->orderProductAttributeCombinationsScheduledForDeletion->getPrimaryKeys(false)) ->delete($con); - $this->orderFeaturesScheduledForDeletion = null; + $this->orderProductAttributeCombinationsScheduledForDeletion = null; } } - if ($this->collOrderFeatures !== null) { - foreach ($this->collOrderFeatures as $referrerFK) { + if ($this->collOrderProductAttributeCombinations !== null) { + foreach ($this->collOrderProductAttributeCombinations as $referrerFK) { + if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { + $affectedRows += $referrerFK->save($con); + } + } + } + + if ($this->orderProductTaxesScheduledForDeletion !== null) { + if (!$this->orderProductTaxesScheduledForDeletion->isEmpty()) { + \Thelia\Model\OrderProductTaxQuery::create() + ->filterByPrimaryKeys($this->orderProductTaxesScheduledForDeletion->getPrimaryKeys(false)) + ->delete($con); + $this->orderProductTaxesScheduledForDeletion = null; + } + } + + if ($this->collOrderProductTaxes !== null) { + foreach ($this->collOrderProductTaxes as $referrerFK) { if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { $affectedRows += $referrerFK->save($con); } @@ -1166,14 +1486,20 @@ abstract class OrderProduct implements ActiveRecordInterface if ($this->isColumnModified(OrderProductTableMap::PRODUCT_REF)) { $modifiedColumns[':p' . $index++] = 'PRODUCT_REF'; } + if ($this->isColumnModified(OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF)) { + $modifiedColumns[':p' . $index++] = 'PRODUCT_SALE_ELEMENTS_REF'; + } if ($this->isColumnModified(OrderProductTableMap::TITLE)) { $modifiedColumns[':p' . $index++] = 'TITLE'; } + if ($this->isColumnModified(OrderProductTableMap::CHAPO)) { + $modifiedColumns[':p' . $index++] = 'CHAPO'; + } if ($this->isColumnModified(OrderProductTableMap::DESCRIPTION)) { $modifiedColumns[':p' . $index++] = 'DESCRIPTION'; } - if ($this->isColumnModified(OrderProductTableMap::CHAPO)) { - $modifiedColumns[':p' . $index++] = 'CHAPO'; + if ($this->isColumnModified(OrderProductTableMap::POSTSCRIPTUM)) { + $modifiedColumns[':p' . $index++] = 'POSTSCRIPTUM'; } if ($this->isColumnModified(OrderProductTableMap::QUANTITY)) { $modifiedColumns[':p' . $index++] = 'QUANTITY'; @@ -1181,8 +1507,23 @@ abstract class OrderProduct implements ActiveRecordInterface if ($this->isColumnModified(OrderProductTableMap::PRICE)) { $modifiedColumns[':p' . $index++] = 'PRICE'; } - if ($this->isColumnModified(OrderProductTableMap::TAX)) { - $modifiedColumns[':p' . $index++] = 'TAX'; + if ($this->isColumnModified(OrderProductTableMap::PROMO_PRICE)) { + $modifiedColumns[':p' . $index++] = 'PROMO_PRICE'; + } + if ($this->isColumnModified(OrderProductTableMap::WAS_NEW)) { + $modifiedColumns[':p' . $index++] = 'WAS_NEW'; + } + if ($this->isColumnModified(OrderProductTableMap::WAS_IN_PROMO)) { + $modifiedColumns[':p' . $index++] = 'WAS_IN_PROMO'; + } + if ($this->isColumnModified(OrderProductTableMap::WEIGHT)) { + $modifiedColumns[':p' . $index++] = 'WEIGHT'; + } + if ($this->isColumnModified(OrderProductTableMap::TAX_RULE_TITLE)) { + $modifiedColumns[':p' . $index++] = 'TAX_RULE_TITLE'; + } + if ($this->isColumnModified(OrderProductTableMap::TAX_RULE_DESCRIPTION)) { + $modifiedColumns[':p' . $index++] = 'TAX_RULE_DESCRIPTION'; } if ($this->isColumnModified(OrderProductTableMap::PARENT)) { $modifiedColumns[':p' . $index++] = 'PARENT'; @@ -1213,14 +1554,20 @@ abstract class OrderProduct implements ActiveRecordInterface case 'PRODUCT_REF': $stmt->bindValue($identifier, $this->product_ref, PDO::PARAM_STR); break; + case 'PRODUCT_SALE_ELEMENTS_REF': + $stmt->bindValue($identifier, $this->product_sale_elements_ref, PDO::PARAM_STR); + break; case 'TITLE': $stmt->bindValue($identifier, $this->title, PDO::PARAM_STR); break; + case 'CHAPO': + $stmt->bindValue($identifier, $this->chapo, PDO::PARAM_STR); + break; case 'DESCRIPTION': $stmt->bindValue($identifier, $this->description, PDO::PARAM_STR); break; - case 'CHAPO': - $stmt->bindValue($identifier, $this->chapo, PDO::PARAM_STR); + case 'POSTSCRIPTUM': + $stmt->bindValue($identifier, $this->postscriptum, PDO::PARAM_STR); break; case 'QUANTITY': $stmt->bindValue($identifier, $this->quantity, PDO::PARAM_STR); @@ -1228,8 +1575,23 @@ abstract class OrderProduct implements ActiveRecordInterface case 'PRICE': $stmt->bindValue($identifier, $this->price, PDO::PARAM_STR); break; - case 'TAX': - $stmt->bindValue($identifier, $this->tax, PDO::PARAM_STR); + case 'PROMO_PRICE': + $stmt->bindValue($identifier, $this->promo_price, PDO::PARAM_STR); + break; + case 'WAS_NEW': + $stmt->bindValue($identifier, $this->was_new, PDO::PARAM_INT); + break; + case 'WAS_IN_PROMO': + $stmt->bindValue($identifier, $this->was_in_promo, PDO::PARAM_INT); + break; + case 'WEIGHT': + $stmt->bindValue($identifier, $this->weight, PDO::PARAM_STR); + break; + case 'TAX_RULE_TITLE': + $stmt->bindValue($identifier, $this->tax_rule_title, PDO::PARAM_STR); + break; + case 'TAX_RULE_DESCRIPTION': + $stmt->bindValue($identifier, $this->tax_rule_description, PDO::PARAM_STR); break; case 'PARENT': $stmt->bindValue($identifier, $this->parent, PDO::PARAM_INT); @@ -1312,30 +1674,51 @@ abstract class OrderProduct implements ActiveRecordInterface return $this->getProductRef(); break; case 3: - return $this->getTitle(); + return $this->getProductSaleElementsRef(); break; case 4: - return $this->getDescription(); + return $this->getTitle(); break; case 5: return $this->getChapo(); break; case 6: - return $this->getQuantity(); + return $this->getDescription(); break; case 7: - return $this->getPrice(); + return $this->getPostscriptum(); break; case 8: - return $this->getTax(); + return $this->getQuantity(); break; case 9: - return $this->getParent(); + return $this->getPrice(); break; case 10: - return $this->getCreatedAt(); + return $this->getPromoPrice(); break; case 11: + return $this->getWasNew(); + break; + case 12: + return $this->getWasInPromo(); + break; + case 13: + return $this->getWeight(); + break; + case 14: + return $this->getTaxRuleTitle(); + break; + case 15: + return $this->getTaxRuleDescription(); + break; + case 16: + return $this->getParent(); + break; + case 17: + return $this->getCreatedAt(); + break; + case 18: return $this->getUpdatedAt(); break; default: @@ -1370,15 +1753,22 @@ abstract class OrderProduct implements ActiveRecordInterface $keys[0] => $this->getId(), $keys[1] => $this->getOrderId(), $keys[2] => $this->getProductRef(), - $keys[3] => $this->getTitle(), - $keys[4] => $this->getDescription(), + $keys[3] => $this->getProductSaleElementsRef(), + $keys[4] => $this->getTitle(), $keys[5] => $this->getChapo(), - $keys[6] => $this->getQuantity(), - $keys[7] => $this->getPrice(), - $keys[8] => $this->getTax(), - $keys[9] => $this->getParent(), - $keys[10] => $this->getCreatedAt(), - $keys[11] => $this->getUpdatedAt(), + $keys[6] => $this->getDescription(), + $keys[7] => $this->getPostscriptum(), + $keys[8] => $this->getQuantity(), + $keys[9] => $this->getPrice(), + $keys[10] => $this->getPromoPrice(), + $keys[11] => $this->getWasNew(), + $keys[12] => $this->getWasInPromo(), + $keys[13] => $this->getWeight(), + $keys[14] => $this->getTaxRuleTitle(), + $keys[15] => $this->getTaxRuleDescription(), + $keys[16] => $this->getParent(), + $keys[17] => $this->getCreatedAt(), + $keys[18] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1390,8 +1780,11 @@ abstract class OrderProduct implements ActiveRecordInterface if (null !== $this->aOrder) { $result['Order'] = $this->aOrder->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); } - if (null !== $this->collOrderFeatures) { - $result['OrderFeatures'] = $this->collOrderFeatures->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + if (null !== $this->collOrderProductAttributeCombinations) { + $result['OrderProductAttributeCombinations'] = $this->collOrderProductAttributeCombinations->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + } + if (null !== $this->collOrderProductTaxes) { + $result['OrderProductTaxes'] = $this->collOrderProductTaxes->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); } } @@ -1437,30 +1830,51 @@ abstract class OrderProduct implements ActiveRecordInterface $this->setProductRef($value); break; case 3: - $this->setTitle($value); + $this->setProductSaleElementsRef($value); break; case 4: - $this->setDescription($value); + $this->setTitle($value); break; case 5: $this->setChapo($value); break; case 6: - $this->setQuantity($value); + $this->setDescription($value); break; case 7: - $this->setPrice($value); + $this->setPostscriptum($value); break; case 8: - $this->setTax($value); + $this->setQuantity($value); break; case 9: - $this->setParent($value); + $this->setPrice($value); break; case 10: - $this->setCreatedAt($value); + $this->setPromoPrice($value); break; case 11: + $this->setWasNew($value); + break; + case 12: + $this->setWasInPromo($value); + break; + case 13: + $this->setWeight($value); + break; + case 14: + $this->setTaxRuleTitle($value); + break; + case 15: + $this->setTaxRuleDescription($value); + break; + case 16: + $this->setParent($value); + break; + case 17: + $this->setCreatedAt($value); + break; + case 18: $this->setUpdatedAt($value); break; } // switch() @@ -1490,15 +1904,22 @@ abstract class OrderProduct implements ActiveRecordInterface if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); if (array_key_exists($keys[1], $arr)) $this->setOrderId($arr[$keys[1]]); if (array_key_exists($keys[2], $arr)) $this->setProductRef($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setTitle($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setDescription($arr[$keys[4]]); + if (array_key_exists($keys[3], $arr)) $this->setProductSaleElementsRef($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setTitle($arr[$keys[4]]); if (array_key_exists($keys[5], $arr)) $this->setChapo($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setQuantity($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setPrice($arr[$keys[7]]); - if (array_key_exists($keys[8], $arr)) $this->setTax($arr[$keys[8]]); - if (array_key_exists($keys[9], $arr)) $this->setParent($arr[$keys[9]]); - if (array_key_exists($keys[10], $arr)) $this->setCreatedAt($arr[$keys[10]]); - if (array_key_exists($keys[11], $arr)) $this->setUpdatedAt($arr[$keys[11]]); + if (array_key_exists($keys[6], $arr)) $this->setDescription($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setPostscriptum($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setQuantity($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setPrice($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setPromoPrice($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setWasNew($arr[$keys[11]]); + if (array_key_exists($keys[12], $arr)) $this->setWasInPromo($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setWeight($arr[$keys[13]]); + if (array_key_exists($keys[14], $arr)) $this->setTaxRuleTitle($arr[$keys[14]]); + if (array_key_exists($keys[15], $arr)) $this->setTaxRuleDescription($arr[$keys[15]]); + if (array_key_exists($keys[16], $arr)) $this->setParent($arr[$keys[16]]); + if (array_key_exists($keys[17], $arr)) $this->setCreatedAt($arr[$keys[17]]); + if (array_key_exists($keys[18], $arr)) $this->setUpdatedAt($arr[$keys[18]]); } /** @@ -1513,12 +1934,19 @@ abstract class OrderProduct implements ActiveRecordInterface if ($this->isColumnModified(OrderProductTableMap::ID)) $criteria->add(OrderProductTableMap::ID, $this->id); if ($this->isColumnModified(OrderProductTableMap::ORDER_ID)) $criteria->add(OrderProductTableMap::ORDER_ID, $this->order_id); if ($this->isColumnModified(OrderProductTableMap::PRODUCT_REF)) $criteria->add(OrderProductTableMap::PRODUCT_REF, $this->product_ref); + if ($this->isColumnModified(OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF)) $criteria->add(OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF, $this->product_sale_elements_ref); if ($this->isColumnModified(OrderProductTableMap::TITLE)) $criteria->add(OrderProductTableMap::TITLE, $this->title); - if ($this->isColumnModified(OrderProductTableMap::DESCRIPTION)) $criteria->add(OrderProductTableMap::DESCRIPTION, $this->description); if ($this->isColumnModified(OrderProductTableMap::CHAPO)) $criteria->add(OrderProductTableMap::CHAPO, $this->chapo); + if ($this->isColumnModified(OrderProductTableMap::DESCRIPTION)) $criteria->add(OrderProductTableMap::DESCRIPTION, $this->description); + if ($this->isColumnModified(OrderProductTableMap::POSTSCRIPTUM)) $criteria->add(OrderProductTableMap::POSTSCRIPTUM, $this->postscriptum); if ($this->isColumnModified(OrderProductTableMap::QUANTITY)) $criteria->add(OrderProductTableMap::QUANTITY, $this->quantity); if ($this->isColumnModified(OrderProductTableMap::PRICE)) $criteria->add(OrderProductTableMap::PRICE, $this->price); - if ($this->isColumnModified(OrderProductTableMap::TAX)) $criteria->add(OrderProductTableMap::TAX, $this->tax); + if ($this->isColumnModified(OrderProductTableMap::PROMO_PRICE)) $criteria->add(OrderProductTableMap::PROMO_PRICE, $this->promo_price); + if ($this->isColumnModified(OrderProductTableMap::WAS_NEW)) $criteria->add(OrderProductTableMap::WAS_NEW, $this->was_new); + if ($this->isColumnModified(OrderProductTableMap::WAS_IN_PROMO)) $criteria->add(OrderProductTableMap::WAS_IN_PROMO, $this->was_in_promo); + if ($this->isColumnModified(OrderProductTableMap::WEIGHT)) $criteria->add(OrderProductTableMap::WEIGHT, $this->weight); + if ($this->isColumnModified(OrderProductTableMap::TAX_RULE_TITLE)) $criteria->add(OrderProductTableMap::TAX_RULE_TITLE, $this->tax_rule_title); + if ($this->isColumnModified(OrderProductTableMap::TAX_RULE_DESCRIPTION)) $criteria->add(OrderProductTableMap::TAX_RULE_DESCRIPTION, $this->tax_rule_description); if ($this->isColumnModified(OrderProductTableMap::PARENT)) $criteria->add(OrderProductTableMap::PARENT, $this->parent); if ($this->isColumnModified(OrderProductTableMap::CREATED_AT)) $criteria->add(OrderProductTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(OrderProductTableMap::UPDATED_AT)) $criteria->add(OrderProductTableMap::UPDATED_AT, $this->updated_at); @@ -1587,12 +2015,19 @@ abstract class OrderProduct implements ActiveRecordInterface { $copyObj->setOrderId($this->getOrderId()); $copyObj->setProductRef($this->getProductRef()); + $copyObj->setProductSaleElementsRef($this->getProductSaleElementsRef()); $copyObj->setTitle($this->getTitle()); - $copyObj->setDescription($this->getDescription()); $copyObj->setChapo($this->getChapo()); + $copyObj->setDescription($this->getDescription()); + $copyObj->setPostscriptum($this->getPostscriptum()); $copyObj->setQuantity($this->getQuantity()); $copyObj->setPrice($this->getPrice()); - $copyObj->setTax($this->getTax()); + $copyObj->setPromoPrice($this->getPromoPrice()); + $copyObj->setWasNew($this->getWasNew()); + $copyObj->setWasInPromo($this->getWasInPromo()); + $copyObj->setWeight($this->getWeight()); + $copyObj->setTaxRuleTitle($this->getTaxRuleTitle()); + $copyObj->setTaxRuleDescription($this->getTaxRuleDescription()); $copyObj->setParent($this->getParent()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -1602,9 +2037,15 @@ abstract class OrderProduct implements ActiveRecordInterface // the getter/setter methods for fkey referrer objects. $copyObj->setNew(false); - foreach ($this->getOrderFeatures() as $relObj) { + foreach ($this->getOrderProductAttributeCombinations() as $relObj) { if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addOrderFeature($relObj->copy($deepCopy)); + $copyObj->addOrderProductAttributeCombination($relObj->copy($deepCopy)); + } + } + + foreach ($this->getOrderProductTaxes() as $relObj) { + if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves + $copyObj->addOrderProductTax($relObj->copy($deepCopy)); } } @@ -1700,37 +2141,40 @@ abstract class OrderProduct implements ActiveRecordInterface */ public function initRelation($relationName) { - if ('OrderFeature' == $relationName) { - return $this->initOrderFeatures(); + if ('OrderProductAttributeCombination' == $relationName) { + return $this->initOrderProductAttributeCombinations(); + } + if ('OrderProductTax' == $relationName) { + return $this->initOrderProductTaxes(); } } /** - * Clears out the collOrderFeatures collection + * Clears out the collOrderProductAttributeCombinations 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 addOrderFeatures() + * @see addOrderProductAttributeCombinations() */ - public function clearOrderFeatures() + public function clearOrderProductAttributeCombinations() { - $this->collOrderFeatures = null; // important to set this to NULL since that means it is uninitialized + $this->collOrderProductAttributeCombinations = null; // important to set this to NULL since that means it is uninitialized } /** - * Reset is the collOrderFeatures collection loaded partially. + * Reset is the collOrderProductAttributeCombinations collection loaded partially. */ - public function resetPartialOrderFeatures($v = true) + public function resetPartialOrderProductAttributeCombinations($v = true) { - $this->collOrderFeaturesPartial = $v; + $this->collOrderProductAttributeCombinationsPartial = $v; } /** - * Initializes the collOrderFeatures collection. + * Initializes the collOrderProductAttributeCombinations collection. * - * By default this just sets the collOrderFeatures collection to an empty array (like clearcollOrderFeatures()); + * By default this just sets the collOrderProductAttributeCombinations collection to an empty array (like clearcollOrderProductAttributeCombinations()); * 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. * @@ -1739,17 +2183,17 @@ abstract class OrderProduct implements ActiveRecordInterface * * @return void */ - public function initOrderFeatures($overrideExisting = true) + public function initOrderProductAttributeCombinations($overrideExisting = true) { - if (null !== $this->collOrderFeatures && !$overrideExisting) { + if (null !== $this->collOrderProductAttributeCombinations && !$overrideExisting) { return; } - $this->collOrderFeatures = new ObjectCollection(); - $this->collOrderFeatures->setModel('\Thelia\Model\OrderFeature'); + $this->collOrderProductAttributeCombinations = new ObjectCollection(); + $this->collOrderProductAttributeCombinations->setModel('\Thelia\Model\OrderProductAttributeCombination'); } /** - * Gets an array of ChildOrderFeature objects which contain a foreign key that references this object. + * Gets an array of ChildOrderProductAttributeCombination 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. @@ -1759,109 +2203,109 @@ abstract class OrderProduct implements ActiveRecordInterface * * @param Criteria $criteria optional Criteria object to narrow the query * @param ConnectionInterface $con optional connection object - * @return Collection|ChildOrderFeature[] List of ChildOrderFeature objects + * @return Collection|ChildOrderProductAttributeCombination[] List of ChildOrderProductAttributeCombination objects * @throws PropelException */ - public function getOrderFeatures($criteria = null, ConnectionInterface $con = null) + public function getOrderProductAttributeCombinations($criteria = null, ConnectionInterface $con = null) { - $partial = $this->collOrderFeaturesPartial && !$this->isNew(); - if (null === $this->collOrderFeatures || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collOrderFeatures) { + $partial = $this->collOrderProductAttributeCombinationsPartial && !$this->isNew(); + if (null === $this->collOrderProductAttributeCombinations || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collOrderProductAttributeCombinations) { // return empty collection - $this->initOrderFeatures(); + $this->initOrderProductAttributeCombinations(); } else { - $collOrderFeatures = ChildOrderFeatureQuery::create(null, $criteria) + $collOrderProductAttributeCombinations = ChildOrderProductAttributeCombinationQuery::create(null, $criteria) ->filterByOrderProduct($this) ->find($con); if (null !== $criteria) { - if (false !== $this->collOrderFeaturesPartial && count($collOrderFeatures)) { - $this->initOrderFeatures(false); + if (false !== $this->collOrderProductAttributeCombinationsPartial && count($collOrderProductAttributeCombinations)) { + $this->initOrderProductAttributeCombinations(false); - foreach ($collOrderFeatures as $obj) { - if (false == $this->collOrderFeatures->contains($obj)) { - $this->collOrderFeatures->append($obj); + foreach ($collOrderProductAttributeCombinations as $obj) { + if (false == $this->collOrderProductAttributeCombinations->contains($obj)) { + $this->collOrderProductAttributeCombinations->append($obj); } } - $this->collOrderFeaturesPartial = true; + $this->collOrderProductAttributeCombinationsPartial = true; } - $collOrderFeatures->getInternalIterator()->rewind(); + $collOrderProductAttributeCombinations->getInternalIterator()->rewind(); - return $collOrderFeatures; + return $collOrderProductAttributeCombinations; } - if ($partial && $this->collOrderFeatures) { - foreach ($this->collOrderFeatures as $obj) { + if ($partial && $this->collOrderProductAttributeCombinations) { + foreach ($this->collOrderProductAttributeCombinations as $obj) { if ($obj->isNew()) { - $collOrderFeatures[] = $obj; + $collOrderProductAttributeCombinations[] = $obj; } } } - $this->collOrderFeatures = $collOrderFeatures; - $this->collOrderFeaturesPartial = false; + $this->collOrderProductAttributeCombinations = $collOrderProductAttributeCombinations; + $this->collOrderProductAttributeCombinationsPartial = false; } } - return $this->collOrderFeatures; + return $this->collOrderProductAttributeCombinations; } /** - * Sets a collection of OrderFeature objects related by a one-to-many relationship + * Sets a collection of OrderProductAttributeCombination 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 $orderFeatures A Propel collection. + * @param Collection $orderProductAttributeCombinations A Propel collection. * @param ConnectionInterface $con Optional connection object * @return ChildOrderProduct The current object (for fluent API support) */ - public function setOrderFeatures(Collection $orderFeatures, ConnectionInterface $con = null) + public function setOrderProductAttributeCombinations(Collection $orderProductAttributeCombinations, ConnectionInterface $con = null) { - $orderFeaturesToDelete = $this->getOrderFeatures(new Criteria(), $con)->diff($orderFeatures); + $orderProductAttributeCombinationsToDelete = $this->getOrderProductAttributeCombinations(new Criteria(), $con)->diff($orderProductAttributeCombinations); - $this->orderFeaturesScheduledForDeletion = $orderFeaturesToDelete; + $this->orderProductAttributeCombinationsScheduledForDeletion = $orderProductAttributeCombinationsToDelete; - foreach ($orderFeaturesToDelete as $orderFeatureRemoved) { - $orderFeatureRemoved->setOrderProduct(null); + foreach ($orderProductAttributeCombinationsToDelete as $orderProductAttributeCombinationRemoved) { + $orderProductAttributeCombinationRemoved->setOrderProduct(null); } - $this->collOrderFeatures = null; - foreach ($orderFeatures as $orderFeature) { - $this->addOrderFeature($orderFeature); + $this->collOrderProductAttributeCombinations = null; + foreach ($orderProductAttributeCombinations as $orderProductAttributeCombination) { + $this->addOrderProductAttributeCombination($orderProductAttributeCombination); } - $this->collOrderFeatures = $orderFeatures; - $this->collOrderFeaturesPartial = false; + $this->collOrderProductAttributeCombinations = $orderProductAttributeCombinations; + $this->collOrderProductAttributeCombinationsPartial = false; return $this; } /** - * Returns the number of related OrderFeature objects. + * Returns the number of related OrderProductAttributeCombination objects. * * @param Criteria $criteria * @param boolean $distinct * @param ConnectionInterface $con - * @return int Count of related OrderFeature objects. + * @return int Count of related OrderProductAttributeCombination objects. * @throws PropelException */ - public function countOrderFeatures(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + public function countOrderProductAttributeCombinations(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) { - $partial = $this->collOrderFeaturesPartial && !$this->isNew(); - if (null === $this->collOrderFeatures || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collOrderFeatures) { + $partial = $this->collOrderProductAttributeCombinationsPartial && !$this->isNew(); + if (null === $this->collOrderProductAttributeCombinations || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collOrderProductAttributeCombinations) { return 0; } if ($partial && !$criteria) { - return count($this->getOrderFeatures()); + return count($this->getOrderProductAttributeCombinations()); } - $query = ChildOrderFeatureQuery::create(null, $criteria); + $query = ChildOrderProductAttributeCombinationQuery::create(null, $criteria); if ($distinct) { $query->distinct(); } @@ -1871,53 +2315,271 @@ abstract class OrderProduct implements ActiveRecordInterface ->count($con); } - return count($this->collOrderFeatures); + return count($this->collOrderProductAttributeCombinations); } /** - * Method called to associate a ChildOrderFeature object to this object - * through the ChildOrderFeature foreign key attribute. + * Method called to associate a ChildOrderProductAttributeCombination object to this object + * through the ChildOrderProductAttributeCombination foreign key attribute. * - * @param ChildOrderFeature $l ChildOrderFeature + * @param ChildOrderProductAttributeCombination $l ChildOrderProductAttributeCombination * @return \Thelia\Model\OrderProduct The current object (for fluent API support) */ - public function addOrderFeature(ChildOrderFeature $l) + public function addOrderProductAttributeCombination(ChildOrderProductAttributeCombination $l) { - if ($this->collOrderFeatures === null) { - $this->initOrderFeatures(); - $this->collOrderFeaturesPartial = true; + if ($this->collOrderProductAttributeCombinations === null) { + $this->initOrderProductAttributeCombinations(); + $this->collOrderProductAttributeCombinationsPartial = true; } - if (!in_array($l, $this->collOrderFeatures->getArrayCopy(), true)) { // only add it if the **same** object is not already associated - $this->doAddOrderFeature($l); + if (!in_array($l, $this->collOrderProductAttributeCombinations->getArrayCopy(), true)) { // only add it if the **same** object is not already associated + $this->doAddOrderProductAttributeCombination($l); } return $this; } /** - * @param OrderFeature $orderFeature The orderFeature object to add. + * @param OrderProductAttributeCombination $orderProductAttributeCombination The orderProductAttributeCombination object to add. */ - protected function doAddOrderFeature($orderFeature) + protected function doAddOrderProductAttributeCombination($orderProductAttributeCombination) { - $this->collOrderFeatures[]= $orderFeature; - $orderFeature->setOrderProduct($this); + $this->collOrderProductAttributeCombinations[]= $orderProductAttributeCombination; + $orderProductAttributeCombination->setOrderProduct($this); } /** - * @param OrderFeature $orderFeature The orderFeature object to remove. + * @param OrderProductAttributeCombination $orderProductAttributeCombination The orderProductAttributeCombination object to remove. * @return ChildOrderProduct The current object (for fluent API support) */ - public function removeOrderFeature($orderFeature) + public function removeOrderProductAttributeCombination($orderProductAttributeCombination) { - if ($this->getOrderFeatures()->contains($orderFeature)) { - $this->collOrderFeatures->remove($this->collOrderFeatures->search($orderFeature)); - if (null === $this->orderFeaturesScheduledForDeletion) { - $this->orderFeaturesScheduledForDeletion = clone $this->collOrderFeatures; - $this->orderFeaturesScheduledForDeletion->clear(); + if ($this->getOrderProductAttributeCombinations()->contains($orderProductAttributeCombination)) { + $this->collOrderProductAttributeCombinations->remove($this->collOrderProductAttributeCombinations->search($orderProductAttributeCombination)); + if (null === $this->orderProductAttributeCombinationsScheduledForDeletion) { + $this->orderProductAttributeCombinationsScheduledForDeletion = clone $this->collOrderProductAttributeCombinations; + $this->orderProductAttributeCombinationsScheduledForDeletion->clear(); } - $this->orderFeaturesScheduledForDeletion[]= clone $orderFeature; - $orderFeature->setOrderProduct(null); + $this->orderProductAttributeCombinationsScheduledForDeletion[]= clone $orderProductAttributeCombination; + $orderProductAttributeCombination->setOrderProduct(null); + } + + return $this; + } + + /** + * Clears out the collOrderProductTaxes 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 addOrderProductTaxes() + */ + public function clearOrderProductTaxes() + { + $this->collOrderProductTaxes = null; // important to set this to NULL since that means it is uninitialized + } + + /** + * Reset is the collOrderProductTaxes collection loaded partially. + */ + public function resetPartialOrderProductTaxes($v = true) + { + $this->collOrderProductTaxesPartial = $v; + } + + /** + * Initializes the collOrderProductTaxes collection. + * + * By default this just sets the collOrderProductTaxes collection to an empty array (like clearcollOrderProductTaxes()); + * 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 initOrderProductTaxes($overrideExisting = true) + { + if (null !== $this->collOrderProductTaxes && !$overrideExisting) { + return; + } + $this->collOrderProductTaxes = new ObjectCollection(); + $this->collOrderProductTaxes->setModel('\Thelia\Model\OrderProductTax'); + } + + /** + * Gets an array of ChildOrderProductTax 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 ChildOrderProduct 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|ChildOrderProductTax[] List of ChildOrderProductTax objects + * @throws PropelException + */ + public function getOrderProductTaxes($criteria = null, ConnectionInterface $con = null) + { + $partial = $this->collOrderProductTaxesPartial && !$this->isNew(); + if (null === $this->collOrderProductTaxes || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collOrderProductTaxes) { + // return empty collection + $this->initOrderProductTaxes(); + } else { + $collOrderProductTaxes = ChildOrderProductTaxQuery::create(null, $criteria) + ->filterByOrderProduct($this) + ->find($con); + + if (null !== $criteria) { + if (false !== $this->collOrderProductTaxesPartial && count($collOrderProductTaxes)) { + $this->initOrderProductTaxes(false); + + foreach ($collOrderProductTaxes as $obj) { + if (false == $this->collOrderProductTaxes->contains($obj)) { + $this->collOrderProductTaxes->append($obj); + } + } + + $this->collOrderProductTaxesPartial = true; + } + + $collOrderProductTaxes->getInternalIterator()->rewind(); + + return $collOrderProductTaxes; + } + + if ($partial && $this->collOrderProductTaxes) { + foreach ($this->collOrderProductTaxes as $obj) { + if ($obj->isNew()) { + $collOrderProductTaxes[] = $obj; + } + } + } + + $this->collOrderProductTaxes = $collOrderProductTaxes; + $this->collOrderProductTaxesPartial = false; + } + } + + return $this->collOrderProductTaxes; + } + + /** + * Sets a collection of OrderProductTax 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 $orderProductTaxes A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return ChildOrderProduct The current object (for fluent API support) + */ + public function setOrderProductTaxes(Collection $orderProductTaxes, ConnectionInterface $con = null) + { + $orderProductTaxesToDelete = $this->getOrderProductTaxes(new Criteria(), $con)->diff($orderProductTaxes); + + + $this->orderProductTaxesScheduledForDeletion = $orderProductTaxesToDelete; + + foreach ($orderProductTaxesToDelete as $orderProductTaxRemoved) { + $orderProductTaxRemoved->setOrderProduct(null); + } + + $this->collOrderProductTaxes = null; + foreach ($orderProductTaxes as $orderProductTax) { + $this->addOrderProductTax($orderProductTax); + } + + $this->collOrderProductTaxes = $orderProductTaxes; + $this->collOrderProductTaxesPartial = false; + + return $this; + } + + /** + * Returns the number of related OrderProductTax objects. + * + * @param Criteria $criteria + * @param boolean $distinct + * @param ConnectionInterface $con + * @return int Count of related OrderProductTax objects. + * @throws PropelException + */ + public function countOrderProductTaxes(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + { + $partial = $this->collOrderProductTaxesPartial && !$this->isNew(); + if (null === $this->collOrderProductTaxes || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collOrderProductTaxes) { + return 0; + } + + if ($partial && !$criteria) { + return count($this->getOrderProductTaxes()); + } + + $query = ChildOrderProductTaxQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByOrderProduct($this) + ->count($con); + } + + return count($this->collOrderProductTaxes); + } + + /** + * Method called to associate a ChildOrderProductTax object to this object + * through the ChildOrderProductTax foreign key attribute. + * + * @param ChildOrderProductTax $l ChildOrderProductTax + * @return \Thelia\Model\OrderProduct The current object (for fluent API support) + */ + public function addOrderProductTax(ChildOrderProductTax $l) + { + if ($this->collOrderProductTaxes === null) { + $this->initOrderProductTaxes(); + $this->collOrderProductTaxesPartial = true; + } + + if (!in_array($l, $this->collOrderProductTaxes->getArrayCopy(), true)) { // only add it if the **same** object is not already associated + $this->doAddOrderProductTax($l); + } + + return $this; + } + + /** + * @param OrderProductTax $orderProductTax The orderProductTax object to add. + */ + protected function doAddOrderProductTax($orderProductTax) + { + $this->collOrderProductTaxes[]= $orderProductTax; + $orderProductTax->setOrderProduct($this); + } + + /** + * @param OrderProductTax $orderProductTax The orderProductTax object to remove. + * @return ChildOrderProduct The current object (for fluent API support) + */ + public function removeOrderProductTax($orderProductTax) + { + if ($this->getOrderProductTaxes()->contains($orderProductTax)) { + $this->collOrderProductTaxes->remove($this->collOrderProductTaxes->search($orderProductTax)); + if (null === $this->orderProductTaxesScheduledForDeletion) { + $this->orderProductTaxesScheduledForDeletion = clone $this->collOrderProductTaxes; + $this->orderProductTaxesScheduledForDeletion->clear(); + } + $this->orderProductTaxesScheduledForDeletion[]= clone $orderProductTax; + $orderProductTax->setOrderProduct(null); } return $this; @@ -1931,12 +2593,19 @@ abstract class OrderProduct implements ActiveRecordInterface $this->id = null; $this->order_id = null; $this->product_ref = null; + $this->product_sale_elements_ref = null; $this->title = null; - $this->description = null; $this->chapo = null; + $this->description = null; + $this->postscriptum = null; $this->quantity = null; $this->price = null; - $this->tax = null; + $this->promo_price = null; + $this->was_new = null; + $this->was_in_promo = null; + $this->weight = null; + $this->tax_rule_title = null; + $this->tax_rule_description = null; $this->parent = null; $this->created_at = null; $this->updated_at = null; @@ -1959,17 +2628,26 @@ abstract class OrderProduct implements ActiveRecordInterface public function clearAllReferences($deep = false) { if ($deep) { - if ($this->collOrderFeatures) { - foreach ($this->collOrderFeatures as $o) { + if ($this->collOrderProductAttributeCombinations) { + foreach ($this->collOrderProductAttributeCombinations as $o) { + $o->clearAllReferences($deep); + } + } + if ($this->collOrderProductTaxes) { + foreach ($this->collOrderProductTaxes as $o) { $o->clearAllReferences($deep); } } } // if ($deep) - if ($this->collOrderFeatures instanceof Collection) { - $this->collOrderFeatures->clearIterator(); + if ($this->collOrderProductAttributeCombinations instanceof Collection) { + $this->collOrderProductAttributeCombinations->clearIterator(); } - $this->collOrderFeatures = null; + $this->collOrderProductAttributeCombinations = null; + if ($this->collOrderProductTaxes instanceof Collection) { + $this->collOrderProductTaxes->clearIterator(); + } + $this->collOrderProductTaxes = null; $this->aOrder = null; } diff --git a/core/lib/Thelia/Model/Base/OrderProductQuery.php b/core/lib/Thelia/Model/Base/OrderProductQuery.php index b007c89e1..f28102dfb 100644 --- a/core/lib/Thelia/Model/Base/OrderProductQuery.php +++ b/core/lib/Thelia/Model/Base/OrderProductQuery.php @@ -24,12 +24,19 @@ use Thelia\Model\Map\OrderProductTableMap; * @method ChildOrderProductQuery orderById($order = Criteria::ASC) Order by the id column * @method ChildOrderProductQuery orderByOrderId($order = Criteria::ASC) Order by the order_id column * @method ChildOrderProductQuery orderByProductRef($order = Criteria::ASC) Order by the product_ref column + * @method ChildOrderProductQuery orderByProductSaleElementsRef($order = Criteria::ASC) Order by the product_sale_elements_ref column * @method ChildOrderProductQuery orderByTitle($order = Criteria::ASC) Order by the title column - * @method ChildOrderProductQuery orderByDescription($order = Criteria::ASC) Order by the description column * @method ChildOrderProductQuery orderByChapo($order = Criteria::ASC) Order by the chapo column + * @method ChildOrderProductQuery orderByDescription($order = Criteria::ASC) Order by the description column + * @method ChildOrderProductQuery orderByPostscriptum($order = Criteria::ASC) Order by the postscriptum column * @method ChildOrderProductQuery orderByQuantity($order = Criteria::ASC) Order by the quantity column * @method ChildOrderProductQuery orderByPrice($order = Criteria::ASC) Order by the price column - * @method ChildOrderProductQuery orderByTax($order = Criteria::ASC) Order by the tax column + * @method ChildOrderProductQuery orderByPromoPrice($order = Criteria::ASC) Order by the promo_price column + * @method ChildOrderProductQuery orderByWasNew($order = Criteria::ASC) Order by the was_new column + * @method ChildOrderProductQuery orderByWasInPromo($order = Criteria::ASC) Order by the was_in_promo column + * @method ChildOrderProductQuery orderByWeight($order = Criteria::ASC) Order by the weight column + * @method ChildOrderProductQuery orderByTaxRuleTitle($order = Criteria::ASC) Order by the tax_rule_title column + * @method ChildOrderProductQuery orderByTaxRuleDescription($order = Criteria::ASC) Order by the tax_rule_description column * @method ChildOrderProductQuery orderByParent($order = Criteria::ASC) Order by the parent column * @method ChildOrderProductQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildOrderProductQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column @@ -37,12 +44,19 @@ use Thelia\Model\Map\OrderProductTableMap; * @method ChildOrderProductQuery groupById() Group by the id column * @method ChildOrderProductQuery groupByOrderId() Group by the order_id column * @method ChildOrderProductQuery groupByProductRef() Group by the product_ref column + * @method ChildOrderProductQuery groupByProductSaleElementsRef() Group by the product_sale_elements_ref column * @method ChildOrderProductQuery groupByTitle() Group by the title column - * @method ChildOrderProductQuery groupByDescription() Group by the description column * @method ChildOrderProductQuery groupByChapo() Group by the chapo column + * @method ChildOrderProductQuery groupByDescription() Group by the description column + * @method ChildOrderProductQuery groupByPostscriptum() Group by the postscriptum column * @method ChildOrderProductQuery groupByQuantity() Group by the quantity column * @method ChildOrderProductQuery groupByPrice() Group by the price column - * @method ChildOrderProductQuery groupByTax() Group by the tax column + * @method ChildOrderProductQuery groupByPromoPrice() Group by the promo_price column + * @method ChildOrderProductQuery groupByWasNew() Group by the was_new column + * @method ChildOrderProductQuery groupByWasInPromo() Group by the was_in_promo column + * @method ChildOrderProductQuery groupByWeight() Group by the weight column + * @method ChildOrderProductQuery groupByTaxRuleTitle() Group by the tax_rule_title column + * @method ChildOrderProductQuery groupByTaxRuleDescription() Group by the tax_rule_description column * @method ChildOrderProductQuery groupByParent() Group by the parent column * @method ChildOrderProductQuery groupByCreatedAt() Group by the created_at column * @method ChildOrderProductQuery groupByUpdatedAt() Group by the updated_at column @@ -55,9 +69,13 @@ use Thelia\Model\Map\OrderProductTableMap; * @method ChildOrderProductQuery rightJoinOrder($relationAlias = null) Adds a RIGHT JOIN clause to the query using the Order relation * @method ChildOrderProductQuery innerJoinOrder($relationAlias = null) Adds a INNER JOIN clause to the query using the Order relation * - * @method ChildOrderProductQuery leftJoinOrderFeature($relationAlias = null) Adds a LEFT JOIN clause to the query using the OrderFeature relation - * @method ChildOrderProductQuery rightJoinOrderFeature($relationAlias = null) Adds a RIGHT JOIN clause to the query using the OrderFeature relation - * @method ChildOrderProductQuery innerJoinOrderFeature($relationAlias = null) Adds a INNER JOIN clause to the query using the OrderFeature relation + * @method ChildOrderProductQuery leftJoinOrderProductAttributeCombination($relationAlias = null) Adds a LEFT JOIN clause to the query using the OrderProductAttributeCombination relation + * @method ChildOrderProductQuery rightJoinOrderProductAttributeCombination($relationAlias = null) Adds a RIGHT JOIN clause to the query using the OrderProductAttributeCombination relation + * @method ChildOrderProductQuery innerJoinOrderProductAttributeCombination($relationAlias = null) Adds a INNER JOIN clause to the query using the OrderProductAttributeCombination relation + * + * @method ChildOrderProductQuery leftJoinOrderProductTax($relationAlias = null) Adds a LEFT JOIN clause to the query using the OrderProductTax relation + * @method ChildOrderProductQuery rightJoinOrderProductTax($relationAlias = null) Adds a RIGHT JOIN clause to the query using the OrderProductTax relation + * @method ChildOrderProductQuery innerJoinOrderProductTax($relationAlias = null) Adds a INNER JOIN clause to the query using the OrderProductTax relation * * @method ChildOrderProduct findOne(ConnectionInterface $con = null) Return the first ChildOrderProduct matching the query * @method ChildOrderProduct findOneOrCreate(ConnectionInterface $con = null) Return the first ChildOrderProduct matching the query, or a new ChildOrderProduct object populated from the query conditions when no match is found @@ -65,12 +83,19 @@ use Thelia\Model\Map\OrderProductTableMap; * @method ChildOrderProduct findOneById(int $id) Return the first ChildOrderProduct filtered by the id column * @method ChildOrderProduct findOneByOrderId(int $order_id) Return the first ChildOrderProduct filtered by the order_id column * @method ChildOrderProduct findOneByProductRef(string $product_ref) Return the first ChildOrderProduct filtered by the product_ref column + * @method ChildOrderProduct findOneByProductSaleElementsRef(string $product_sale_elements_ref) Return the first ChildOrderProduct filtered by the product_sale_elements_ref column * @method ChildOrderProduct findOneByTitle(string $title) Return the first ChildOrderProduct filtered by the title column - * @method ChildOrderProduct findOneByDescription(string $description) Return the first ChildOrderProduct filtered by the description column * @method ChildOrderProduct findOneByChapo(string $chapo) Return the first ChildOrderProduct filtered by the chapo column + * @method ChildOrderProduct findOneByDescription(string $description) Return the first ChildOrderProduct filtered by the description column + * @method ChildOrderProduct findOneByPostscriptum(string $postscriptum) Return the first ChildOrderProduct filtered by the postscriptum column * @method ChildOrderProduct findOneByQuantity(double $quantity) Return the first ChildOrderProduct filtered by the quantity column * @method ChildOrderProduct findOneByPrice(double $price) Return the first ChildOrderProduct filtered by the price column - * @method ChildOrderProduct findOneByTax(double $tax) Return the first ChildOrderProduct filtered by the tax column + * @method ChildOrderProduct findOneByPromoPrice(string $promo_price) Return the first ChildOrderProduct filtered by the promo_price column + * @method ChildOrderProduct findOneByWasNew(int $was_new) Return the first ChildOrderProduct filtered by the was_new column + * @method ChildOrderProduct findOneByWasInPromo(int $was_in_promo) Return the first ChildOrderProduct filtered by the was_in_promo column + * @method ChildOrderProduct findOneByWeight(string $weight) Return the first ChildOrderProduct filtered by the weight column + * @method ChildOrderProduct findOneByTaxRuleTitle(string $tax_rule_title) Return the first ChildOrderProduct filtered by the tax_rule_title column + * @method ChildOrderProduct findOneByTaxRuleDescription(string $tax_rule_description) Return the first ChildOrderProduct filtered by the tax_rule_description column * @method ChildOrderProduct findOneByParent(int $parent) Return the first ChildOrderProduct filtered by the parent column * @method ChildOrderProduct findOneByCreatedAt(string $created_at) Return the first ChildOrderProduct filtered by the created_at column * @method ChildOrderProduct findOneByUpdatedAt(string $updated_at) Return the first ChildOrderProduct filtered by the updated_at column @@ -78,12 +103,19 @@ use Thelia\Model\Map\OrderProductTableMap; * @method array findById(int $id) Return ChildOrderProduct objects filtered by the id column * @method array findByOrderId(int $order_id) Return ChildOrderProduct objects filtered by the order_id column * @method array findByProductRef(string $product_ref) Return ChildOrderProduct objects filtered by the product_ref column + * @method array findByProductSaleElementsRef(string $product_sale_elements_ref) Return ChildOrderProduct objects filtered by the product_sale_elements_ref column * @method array findByTitle(string $title) Return ChildOrderProduct objects filtered by the title column - * @method array findByDescription(string $description) Return ChildOrderProduct objects filtered by the description column * @method array findByChapo(string $chapo) Return ChildOrderProduct objects filtered by the chapo column + * @method array findByDescription(string $description) Return ChildOrderProduct objects filtered by the description column + * @method array findByPostscriptum(string $postscriptum) Return ChildOrderProduct objects filtered by the postscriptum column * @method array findByQuantity(double $quantity) Return ChildOrderProduct objects filtered by the quantity column * @method array findByPrice(double $price) Return ChildOrderProduct objects filtered by the price column - * @method array findByTax(double $tax) Return ChildOrderProduct objects filtered by the tax column + * @method array findByPromoPrice(string $promo_price) Return ChildOrderProduct objects filtered by the promo_price column + * @method array findByWasNew(int $was_new) Return ChildOrderProduct objects filtered by the was_new column + * @method array findByWasInPromo(int $was_in_promo) Return ChildOrderProduct objects filtered by the was_in_promo column + * @method array findByWeight(string $weight) Return ChildOrderProduct objects filtered by the weight column + * @method array findByTaxRuleTitle(string $tax_rule_title) Return ChildOrderProduct objects filtered by the tax_rule_title column + * @method array findByTaxRuleDescription(string $tax_rule_description) Return ChildOrderProduct objects filtered by the tax_rule_description column * @method array findByParent(int $parent) Return ChildOrderProduct objects filtered by the parent column * @method array findByCreatedAt(string $created_at) Return ChildOrderProduct objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildOrderProduct objects filtered by the updated_at column @@ -175,7 +207,7 @@ abstract class OrderProductQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, ORDER_ID, PRODUCT_REF, TITLE, DESCRIPTION, CHAPO, QUANTITY, PRICE, TAX, PARENT, CREATED_AT, UPDATED_AT FROM order_product WHERE ID = :p0'; + $sql = 'SELECT ID, ORDER_ID, PRODUCT_REF, PRODUCT_SALE_ELEMENTS_REF, TITLE, CHAPO, DESCRIPTION, POSTSCRIPTUM, QUANTITY, PRICE, PROMO_PRICE, WAS_NEW, WAS_IN_PROMO, WEIGHT, TAX_RULE_TITLE, TAX_RULE_DESCRIPTION, PARENT, CREATED_AT, UPDATED_AT FROM order_product WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -377,6 +409,35 @@ abstract class OrderProductQuery extends ModelCriteria return $this->addUsingAlias(OrderProductTableMap::PRODUCT_REF, $productRef, $comparison); } + /** + * Filter the query on the product_sale_elements_ref column + * + * Example usage: + * + * $query->filterByProductSaleElementsRef('fooValue'); // WHERE product_sale_elements_ref = 'fooValue' + * $query->filterByProductSaleElementsRef('%fooValue%'); // WHERE product_sale_elements_ref LIKE '%fooValue%' + * + * + * @param string $productSaleElementsRef 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 ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByProductSaleElementsRef($productSaleElementsRef = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($productSaleElementsRef)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $productSaleElementsRef)) { + $productSaleElementsRef = str_replace('*', '%', $productSaleElementsRef); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF, $productSaleElementsRef, $comparison); + } + /** * Filter the query on the title column * @@ -406,6 +467,35 @@ abstract class OrderProductQuery extends ModelCriteria return $this->addUsingAlias(OrderProductTableMap::TITLE, $title, $comparison); } + /** + * Filter the query on the chapo column + * + * Example usage: + * + * $query->filterByChapo('fooValue'); // WHERE chapo = 'fooValue' + * $query->filterByChapo('%fooValue%'); // WHERE chapo LIKE '%fooValue%' + * + * + * @param string $chapo 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 ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByChapo($chapo = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($chapo)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $chapo)) { + $chapo = str_replace('*', '%', $chapo); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTableMap::CHAPO, $chapo, $comparison); + } + /** * Filter the query on the description column * @@ -436,32 +526,32 @@ abstract class OrderProductQuery extends ModelCriteria } /** - * Filter the query on the chapo column + * Filter the query on the postscriptum column * * Example usage: * - * $query->filterByChapo('fooValue'); // WHERE chapo = 'fooValue' - * $query->filterByChapo('%fooValue%'); // WHERE chapo LIKE '%fooValue%' + * $query->filterByPostscriptum('fooValue'); // WHERE postscriptum = 'fooValue' + * $query->filterByPostscriptum('%fooValue%'); // WHERE postscriptum LIKE '%fooValue%' * * - * @param string $chapo The value to use as filter. + * @param string $postscriptum 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 ChildOrderProductQuery The current query, for fluid interface */ - public function filterByChapo($chapo = null, $comparison = null) + public function filterByPostscriptum($postscriptum = null, $comparison = null) { if (null === $comparison) { - if (is_array($chapo)) { + if (is_array($postscriptum)) { $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $chapo)) { - $chapo = str_replace('*', '%', $chapo); + } elseif (preg_match('/[\%\*]/', $postscriptum)) { + $postscriptum = str_replace('*', '%', $postscriptum); $comparison = Criteria::LIKE; } } - return $this->addUsingAlias(OrderProductTableMap::CHAPO, $chapo, $comparison); + return $this->addUsingAlias(OrderProductTableMap::POSTSCRIPTUM, $postscriptum, $comparison); } /** @@ -547,16 +637,45 @@ abstract class OrderProductQuery extends ModelCriteria } /** - * Filter the query on the tax column + * Filter the query on the promo_price column * * Example usage: * - * $query->filterByTax(1234); // WHERE tax = 1234 - * $query->filterByTax(array(12, 34)); // WHERE tax IN (12, 34) - * $query->filterByTax(array('min' => 12)); // WHERE tax > 12 + * $query->filterByPromoPrice('fooValue'); // WHERE promo_price = 'fooValue' + * $query->filterByPromoPrice('%fooValue%'); // WHERE promo_price LIKE '%fooValue%' * * - * @param mixed $tax The value to use as filter. + * @param string $promoPrice 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 ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByPromoPrice($promoPrice = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($promoPrice)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $promoPrice)) { + $promoPrice = str_replace('*', '%', $promoPrice); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTableMap::PROMO_PRICE, $promoPrice, $comparison); + } + + /** + * Filter the query on the was_new column + * + * Example usage: + * + * $query->filterByWasNew(1234); // WHERE was_new = 1234 + * $query->filterByWasNew(array(12, 34)); // WHERE was_new IN (12, 34) + * $query->filterByWasNew(array('min' => 12)); // WHERE was_new > 12 + * + * + * @param mixed $wasNew 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. @@ -564,16 +683,16 @@ abstract class OrderProductQuery extends ModelCriteria * * @return ChildOrderProductQuery The current query, for fluid interface */ - public function filterByTax($tax = null, $comparison = null) + public function filterByWasNew($wasNew = null, $comparison = null) { - if (is_array($tax)) { + if (is_array($wasNew)) { $useMinMax = false; - if (isset($tax['min'])) { - $this->addUsingAlias(OrderProductTableMap::TAX, $tax['min'], Criteria::GREATER_EQUAL); + if (isset($wasNew['min'])) { + $this->addUsingAlias(OrderProductTableMap::WAS_NEW, $wasNew['min'], Criteria::GREATER_EQUAL); $useMinMax = true; } - if (isset($tax['max'])) { - $this->addUsingAlias(OrderProductTableMap::TAX, $tax['max'], Criteria::LESS_EQUAL); + if (isset($wasNew['max'])) { + $this->addUsingAlias(OrderProductTableMap::WAS_NEW, $wasNew['max'], Criteria::LESS_EQUAL); $useMinMax = true; } if ($useMinMax) { @@ -584,7 +703,135 @@ abstract class OrderProductQuery extends ModelCriteria } } - return $this->addUsingAlias(OrderProductTableMap::TAX, $tax, $comparison); + return $this->addUsingAlias(OrderProductTableMap::WAS_NEW, $wasNew, $comparison); + } + + /** + * Filter the query on the was_in_promo column + * + * Example usage: + * + * $query->filterByWasInPromo(1234); // WHERE was_in_promo = 1234 + * $query->filterByWasInPromo(array(12, 34)); // WHERE was_in_promo IN (12, 34) + * $query->filterByWasInPromo(array('min' => 12)); // WHERE was_in_promo > 12 + * + * + * @param mixed $wasInPromo 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 ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByWasInPromo($wasInPromo = null, $comparison = null) + { + if (is_array($wasInPromo)) { + $useMinMax = false; + if (isset($wasInPromo['min'])) { + $this->addUsingAlias(OrderProductTableMap::WAS_IN_PROMO, $wasInPromo['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($wasInPromo['max'])) { + $this->addUsingAlias(OrderProductTableMap::WAS_IN_PROMO, $wasInPromo['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductTableMap::WAS_IN_PROMO, $wasInPromo, $comparison); + } + + /** + * Filter the query on the weight column + * + * Example usage: + * + * $query->filterByWeight('fooValue'); // WHERE weight = 'fooValue' + * $query->filterByWeight('%fooValue%'); // WHERE weight LIKE '%fooValue%' + * + * + * @param string $weight 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 ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByWeight($weight = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($weight)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $weight)) { + $weight = str_replace('*', '%', $weight); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTableMap::WEIGHT, $weight, $comparison); + } + + /** + * Filter the query on the tax_rule_title column + * + * Example usage: + * + * $query->filterByTaxRuleTitle('fooValue'); // WHERE tax_rule_title = 'fooValue' + * $query->filterByTaxRuleTitle('%fooValue%'); // WHERE tax_rule_title LIKE '%fooValue%' + * + * + * @param string $taxRuleTitle 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 ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByTaxRuleTitle($taxRuleTitle = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($taxRuleTitle)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $taxRuleTitle)) { + $taxRuleTitle = str_replace('*', '%', $taxRuleTitle); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTableMap::TAX_RULE_TITLE, $taxRuleTitle, $comparison); + } + + /** + * Filter the query on the tax_rule_description column + * + * Example usage: + * + * $query->filterByTaxRuleDescription('fooValue'); // WHERE tax_rule_description = 'fooValue' + * $query->filterByTaxRuleDescription('%fooValue%'); // WHERE tax_rule_description LIKE '%fooValue%' + * + * + * @param string $taxRuleDescription 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 ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByTaxRuleDescription($taxRuleDescription = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($taxRuleDescription)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $taxRuleDescription)) { + $taxRuleDescription = str_replace('*', '%', $taxRuleDescription); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTableMap::TAX_RULE_DESCRIPTION, $taxRuleDescription, $comparison); } /** @@ -790,40 +1037,40 @@ abstract class OrderProductQuery extends ModelCriteria } /** - * Filter the query by a related \Thelia\Model\OrderFeature object + * Filter the query by a related \Thelia\Model\OrderProductAttributeCombination object * - * @param \Thelia\Model\OrderFeature|ObjectCollection $orderFeature the related object to use as filter + * @param \Thelia\Model\OrderProductAttributeCombination|ObjectCollection $orderProductAttributeCombination the related object to use as filter * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * * @return ChildOrderProductQuery The current query, for fluid interface */ - public function filterByOrderFeature($orderFeature, $comparison = null) + public function filterByOrderProductAttributeCombination($orderProductAttributeCombination, $comparison = null) { - if ($orderFeature instanceof \Thelia\Model\OrderFeature) { + if ($orderProductAttributeCombination instanceof \Thelia\Model\OrderProductAttributeCombination) { return $this - ->addUsingAlias(OrderProductTableMap::ID, $orderFeature->getOrderProductId(), $comparison); - } elseif ($orderFeature instanceof ObjectCollection) { + ->addUsingAlias(OrderProductTableMap::ID, $orderProductAttributeCombination->getOrderProductId(), $comparison); + } elseif ($orderProductAttributeCombination instanceof ObjectCollection) { return $this - ->useOrderFeatureQuery() - ->filterByPrimaryKeys($orderFeature->getPrimaryKeys()) + ->useOrderProductAttributeCombinationQuery() + ->filterByPrimaryKeys($orderProductAttributeCombination->getPrimaryKeys()) ->endUse(); } else { - throw new PropelException('filterByOrderFeature() only accepts arguments of type \Thelia\Model\OrderFeature or Collection'); + throw new PropelException('filterByOrderProductAttributeCombination() only accepts arguments of type \Thelia\Model\OrderProductAttributeCombination or Collection'); } } /** - * Adds a JOIN clause to the query using the OrderFeature relation + * Adds a JOIN clause to the query using the OrderProductAttributeCombination relation * * @param string $relationAlias optional alias for the relation * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * * @return ChildOrderProductQuery The current query, for fluid interface */ - public function joinOrderFeature($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function joinOrderProductAttributeCombination($relationAlias = null, $joinType = Criteria::INNER_JOIN) { $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('OrderFeature'); + $relationMap = $tableMap->getRelation('OrderProductAttributeCombination'); // create a ModelJoin object for this join $join = new ModelJoin(); @@ -838,14 +1085,14 @@ abstract class OrderProductQuery extends ModelCriteria $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); $this->addJoinObject($join, $relationAlias); } else { - $this->addJoinObject($join, 'OrderFeature'); + $this->addJoinObject($join, 'OrderProductAttributeCombination'); } return $this; } /** - * Use the OrderFeature relation OrderFeature object + * Use the OrderProductAttributeCombination relation OrderProductAttributeCombination object * * @see useQuery() * @@ -853,13 +1100,86 @@ abstract class OrderProductQuery 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\OrderFeatureQuery A secondary query class using the current class as primary query + * @return \Thelia\Model\OrderProductAttributeCombinationQuery A secondary query class using the current class as primary query */ - public function useOrderFeatureQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function useOrderProductAttributeCombinationQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) { return $this - ->joinOrderFeature($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'OrderFeature', '\Thelia\Model\OrderFeatureQuery'); + ->joinOrderProductAttributeCombination($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'OrderProductAttributeCombination', '\Thelia\Model\OrderProductAttributeCombinationQuery'); + } + + /** + * Filter the query by a related \Thelia\Model\OrderProductTax object + * + * @param \Thelia\Model\OrderProductTax|ObjectCollection $orderProductTax the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductQuery The current query, for fluid interface + */ + public function filterByOrderProductTax($orderProductTax, $comparison = null) + { + if ($orderProductTax instanceof \Thelia\Model\OrderProductTax) { + return $this + ->addUsingAlias(OrderProductTableMap::ID, $orderProductTax->getOrderProductId(), $comparison); + } elseif ($orderProductTax instanceof ObjectCollection) { + return $this + ->useOrderProductTaxQuery() + ->filterByPrimaryKeys($orderProductTax->getPrimaryKeys()) + ->endUse(); + } else { + throw new PropelException('filterByOrderProductTax() only accepts arguments of type \Thelia\Model\OrderProductTax or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the OrderProductTax relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildOrderProductQuery The current query, for fluid interface + */ + public function joinOrderProductTax($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('OrderProductTax'); + + // 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, 'OrderProductTax'); + } + + return $this; + } + + /** + * Use the OrderProductTax relation OrderProductTax 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\OrderProductTaxQuery A secondary query class using the current class as primary query + */ + public function useOrderProductTaxQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinOrderProductTax($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'OrderProductTax', '\Thelia\Model\OrderProductTaxQuery'); } /** diff --git a/core/lib/Thelia/Model/FeatureProduct.php b/core/lib/Thelia/Model/FeatureProduct.php index 35a9b2ddc..fe6c5d8c1 100755 --- a/core/lib/Thelia/Model/FeatureProduct.php +++ b/core/lib/Thelia/Model/FeatureProduct.php @@ -3,8 +3,66 @@ namespace Thelia\Model; use Thelia\Model\Base\FeatureProduct as BaseFeatureProduct; +use Thelia\Core\Event\TheliaEvents; +use Propel\Runtime\Connection\ConnectionInterface; +use Thelia\Core\Event\FeatureProductEvent; - class FeatureProduct extends BaseFeatureProduct +class FeatureProduct extends BaseFeatureProduct { + use \Thelia\Model\Tools\ModelEventDispatcherTrait; + + /** + * {@inheritDoc} + */ + public function preInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_CREATEFEATURE_PRODUCT, new FeatureProductEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_CREATEFEATURE_PRODUCT, new FeatureProductEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_UPDATEFEATURE_PRODUCT, new FeatureProductEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_UPDATEFEATURE_PRODUCT, new FeatureProductEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_DELETEFEATURE_PRODUCT, new FeatureProductEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_DELETEFEATURE_PRODUCT, new FeatureProductEvent($this)); + } } diff --git a/core/lib/Thelia/Model/Map/AttributeCombinationTableMap.php b/core/lib/Thelia/Model/Map/AttributeCombinationTableMap.php index c13b85bbf..031ecfd81 100644 --- a/core/lib/Thelia/Model/Map/AttributeCombinationTableMap.php +++ b/core/lib/Thelia/Model/Map/AttributeCombinationTableMap.php @@ -57,7 +57,7 @@ class AttributeCombinationTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 5; + const NUM_COLUMNS = 6; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class AttributeCombinationTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 5; + const NUM_HYDRATE_COLUMNS = 6; /** * the column name for the ATTRIBUTE_ID field @@ -84,6 +84,11 @@ class AttributeCombinationTableMap extends TableMap */ const PRODUCT_SALE_ELEMENTS_ID = 'attribute_combination.PRODUCT_SALE_ELEMENTS_ID'; + /** + * the column name for the IS_DEFAULT field + */ + const IS_DEFAULT = 'attribute_combination.IS_DEFAULT'; + /** * the column name for the CREATED_AT field */ @@ -106,12 +111,12 @@ class AttributeCombinationTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('AttributeId', 'AttributeAvId', 'ProductSaleElementsId', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('attributeId', 'attributeAvId', 'productSaleElementsId', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(AttributeCombinationTableMap::ATTRIBUTE_ID, AttributeCombinationTableMap::ATTRIBUTE_AV_ID, AttributeCombinationTableMap::PRODUCT_SALE_ELEMENTS_ID, AttributeCombinationTableMap::CREATED_AT, AttributeCombinationTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ATTRIBUTE_ID', 'ATTRIBUTE_AV_ID', 'PRODUCT_SALE_ELEMENTS_ID', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('attribute_id', 'attribute_av_id', 'product_sale_elements_id', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + self::TYPE_PHPNAME => array('AttributeId', 'AttributeAvId', 'ProductSaleElementsId', 'IsDefault', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('attributeId', 'attributeAvId', 'productSaleElementsId', 'isDefault', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(AttributeCombinationTableMap::ATTRIBUTE_ID, AttributeCombinationTableMap::ATTRIBUTE_AV_ID, AttributeCombinationTableMap::PRODUCT_SALE_ELEMENTS_ID, AttributeCombinationTableMap::IS_DEFAULT, AttributeCombinationTableMap::CREATED_AT, AttributeCombinationTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ATTRIBUTE_ID', 'ATTRIBUTE_AV_ID', 'PRODUCT_SALE_ELEMENTS_ID', 'IS_DEFAULT', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('attribute_id', 'attribute_av_id', 'product_sale_elements_id', 'is_default', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) ); /** @@ -121,12 +126,12 @@ class AttributeCombinationTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('AttributeId' => 0, 'AttributeAvId' => 1, 'ProductSaleElementsId' => 2, 'CreatedAt' => 3, 'UpdatedAt' => 4, ), - self::TYPE_STUDLYPHPNAME => array('attributeId' => 0, 'attributeAvId' => 1, 'productSaleElementsId' => 2, 'createdAt' => 3, 'updatedAt' => 4, ), - self::TYPE_COLNAME => array(AttributeCombinationTableMap::ATTRIBUTE_ID => 0, AttributeCombinationTableMap::ATTRIBUTE_AV_ID => 1, AttributeCombinationTableMap::PRODUCT_SALE_ELEMENTS_ID => 2, AttributeCombinationTableMap::CREATED_AT => 3, AttributeCombinationTableMap::UPDATED_AT => 4, ), - self::TYPE_RAW_COLNAME => array('ATTRIBUTE_ID' => 0, 'ATTRIBUTE_AV_ID' => 1, 'PRODUCT_SALE_ELEMENTS_ID' => 2, 'CREATED_AT' => 3, 'UPDATED_AT' => 4, ), - self::TYPE_FIELDNAME => array('attribute_id' => 0, 'attribute_av_id' => 1, 'product_sale_elements_id' => 2, 'created_at' => 3, 'updated_at' => 4, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + self::TYPE_PHPNAME => array('AttributeId' => 0, 'AttributeAvId' => 1, 'ProductSaleElementsId' => 2, 'IsDefault' => 3, 'CreatedAt' => 4, 'UpdatedAt' => 5, ), + self::TYPE_STUDLYPHPNAME => array('attributeId' => 0, 'attributeAvId' => 1, 'productSaleElementsId' => 2, 'isDefault' => 3, 'createdAt' => 4, 'updatedAt' => 5, ), + self::TYPE_COLNAME => array(AttributeCombinationTableMap::ATTRIBUTE_ID => 0, AttributeCombinationTableMap::ATTRIBUTE_AV_ID => 1, AttributeCombinationTableMap::PRODUCT_SALE_ELEMENTS_ID => 2, AttributeCombinationTableMap::IS_DEFAULT => 3, AttributeCombinationTableMap::CREATED_AT => 4, AttributeCombinationTableMap::UPDATED_AT => 5, ), + self::TYPE_RAW_COLNAME => array('ATTRIBUTE_ID' => 0, 'ATTRIBUTE_AV_ID' => 1, 'PRODUCT_SALE_ELEMENTS_ID' => 2, 'IS_DEFAULT' => 3, 'CREATED_AT' => 4, 'UPDATED_AT' => 5, ), + self::TYPE_FIELDNAME => array('attribute_id' => 0, 'attribute_av_id' => 1, 'product_sale_elements_id' => 2, 'is_default' => 3, 'created_at' => 4, 'updated_at' => 5, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) ); /** @@ -148,6 +153,7 @@ class AttributeCombinationTableMap extends TableMap $this->addForeignPrimaryKey('ATTRIBUTE_ID', 'AttributeId', 'INTEGER' , 'attribute', 'ID', true, null, null); $this->addForeignPrimaryKey('ATTRIBUTE_AV_ID', 'AttributeAvId', 'INTEGER' , 'attribute_av', 'ID', true, null, null); $this->addForeignPrimaryKey('PRODUCT_SALE_ELEMENTS_ID', 'ProductSaleElementsId', 'INTEGER' , 'product_sale_elements', 'ID', true, null, null); + $this->addColumn('IS_DEFAULT', 'IsDefault', 'BOOLEAN', false, 1, false); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() @@ -365,12 +371,14 @@ class AttributeCombinationTableMap extends TableMap $criteria->addSelectColumn(AttributeCombinationTableMap::ATTRIBUTE_ID); $criteria->addSelectColumn(AttributeCombinationTableMap::ATTRIBUTE_AV_ID); $criteria->addSelectColumn(AttributeCombinationTableMap::PRODUCT_SALE_ELEMENTS_ID); + $criteria->addSelectColumn(AttributeCombinationTableMap::IS_DEFAULT); $criteria->addSelectColumn(AttributeCombinationTableMap::CREATED_AT); $criteria->addSelectColumn(AttributeCombinationTableMap::UPDATED_AT); } else { $criteria->addSelectColumn($alias . '.ATTRIBUTE_ID'); $criteria->addSelectColumn($alias . '.ATTRIBUTE_AV_ID'); $criteria->addSelectColumn($alias . '.PRODUCT_SALE_ELEMENTS_ID'); + $criteria->addSelectColumn($alias . '.IS_DEFAULT'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); } diff --git a/core/lib/Thelia/Model/Map/FeatureProductTableMap.php b/core/lib/Thelia/Model/Map/FeatureProductTableMap.php index f0263b47c..9db4ec441 100644 --- a/core/lib/Thelia/Model/Map/FeatureProductTableMap.php +++ b/core/lib/Thelia/Model/Map/FeatureProductTableMap.php @@ -90,9 +90,9 @@ class FeatureProductTableMap extends TableMap const FEATURE_AV_ID = 'feature_product.FEATURE_AV_ID'; /** - * the column name for the BY_DEFAULT field + * the column name for the FREE_TEXT_VALUE field */ - const BY_DEFAULT = 'feature_product.BY_DEFAULT'; + const FREE_TEXT_VALUE = 'feature_product.FREE_TEXT_VALUE'; /** * the column name for the POSITION field @@ -121,11 +121,11 @@ class FeatureProductTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'ProductId', 'FeatureId', 'FeatureAvId', 'ByDefault', 'Position', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'productId', 'featureId', 'featureAvId', 'byDefault', 'position', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(FeatureProductTableMap::ID, FeatureProductTableMap::PRODUCT_ID, FeatureProductTableMap::FEATURE_ID, FeatureProductTableMap::FEATURE_AV_ID, FeatureProductTableMap::BY_DEFAULT, FeatureProductTableMap::POSITION, FeatureProductTableMap::CREATED_AT, FeatureProductTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'PRODUCT_ID', 'FEATURE_ID', 'FEATURE_AV_ID', 'BY_DEFAULT', 'POSITION', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'product_id', 'feature_id', 'feature_av_id', 'by_default', 'position', 'created_at', 'updated_at', ), + self::TYPE_PHPNAME => array('Id', 'ProductId', 'FeatureId', 'FeatureAvId', 'FreeTextValue', 'Position', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'productId', 'featureId', 'featureAvId', 'freeTextValue', 'position', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(FeatureProductTableMap::ID, FeatureProductTableMap::PRODUCT_ID, FeatureProductTableMap::FEATURE_ID, FeatureProductTableMap::FEATURE_AV_ID, FeatureProductTableMap::FREE_TEXT_VALUE, FeatureProductTableMap::POSITION, FeatureProductTableMap::CREATED_AT, FeatureProductTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'PRODUCT_ID', 'FEATURE_ID', 'FEATURE_AV_ID', 'FREE_TEXT_VALUE', 'POSITION', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'product_id', 'feature_id', 'feature_av_id', 'free_text_value', 'position', 'created_at', 'updated_at', ), self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) ); @@ -136,11 +136,11 @@ class FeatureProductTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'ProductId' => 1, 'FeatureId' => 2, 'FeatureAvId' => 3, 'ByDefault' => 4, 'Position' => 5, 'CreatedAt' => 6, 'UpdatedAt' => 7, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'productId' => 1, 'featureId' => 2, 'featureAvId' => 3, 'byDefault' => 4, 'position' => 5, 'createdAt' => 6, 'updatedAt' => 7, ), - self::TYPE_COLNAME => array(FeatureProductTableMap::ID => 0, FeatureProductTableMap::PRODUCT_ID => 1, FeatureProductTableMap::FEATURE_ID => 2, FeatureProductTableMap::FEATURE_AV_ID => 3, FeatureProductTableMap::BY_DEFAULT => 4, FeatureProductTableMap::POSITION => 5, FeatureProductTableMap::CREATED_AT => 6, FeatureProductTableMap::UPDATED_AT => 7, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'PRODUCT_ID' => 1, 'FEATURE_ID' => 2, 'FEATURE_AV_ID' => 3, 'BY_DEFAULT' => 4, 'POSITION' => 5, 'CREATED_AT' => 6, 'UPDATED_AT' => 7, ), - self::TYPE_FIELDNAME => array('id' => 0, 'product_id' => 1, 'feature_id' => 2, 'feature_av_id' => 3, 'by_default' => 4, 'position' => 5, 'created_at' => 6, 'updated_at' => 7, ), + self::TYPE_PHPNAME => array('Id' => 0, 'ProductId' => 1, 'FeatureId' => 2, 'FeatureAvId' => 3, 'FreeTextValue' => 4, 'Position' => 5, 'CreatedAt' => 6, 'UpdatedAt' => 7, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'productId' => 1, 'featureId' => 2, 'featureAvId' => 3, 'freeTextValue' => 4, 'position' => 5, 'createdAt' => 6, 'updatedAt' => 7, ), + self::TYPE_COLNAME => array(FeatureProductTableMap::ID => 0, FeatureProductTableMap::PRODUCT_ID => 1, FeatureProductTableMap::FEATURE_ID => 2, FeatureProductTableMap::FEATURE_AV_ID => 3, FeatureProductTableMap::FREE_TEXT_VALUE => 4, FeatureProductTableMap::POSITION => 5, FeatureProductTableMap::CREATED_AT => 6, FeatureProductTableMap::UPDATED_AT => 7, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'PRODUCT_ID' => 1, 'FEATURE_ID' => 2, 'FEATURE_AV_ID' => 3, 'FREE_TEXT_VALUE' => 4, 'POSITION' => 5, 'CREATED_AT' => 6, 'UPDATED_AT' => 7, ), + self::TYPE_FIELDNAME => array('id' => 0, 'product_id' => 1, 'feature_id' => 2, 'feature_av_id' => 3, 'free_text_value' => 4, 'position' => 5, 'created_at' => 6, 'updated_at' => 7, ), self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) ); @@ -164,7 +164,7 @@ class FeatureProductTableMap extends TableMap $this->addForeignKey('PRODUCT_ID', 'ProductId', 'INTEGER', 'product', 'ID', true, null, null); $this->addForeignKey('FEATURE_ID', 'FeatureId', 'INTEGER', 'feature', 'ID', true, null, null); $this->addForeignKey('FEATURE_AV_ID', 'FeatureAvId', 'INTEGER', 'feature_av', 'ID', false, null, null); - $this->addColumn('BY_DEFAULT', 'ByDefault', 'VARCHAR', false, 255, null); + $this->addColumn('FREE_TEXT_VALUE', 'FreeTextValue', 'LONGVARCHAR', false, null, null); $this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); @@ -335,7 +335,7 @@ class FeatureProductTableMap extends TableMap $criteria->addSelectColumn(FeatureProductTableMap::PRODUCT_ID); $criteria->addSelectColumn(FeatureProductTableMap::FEATURE_ID); $criteria->addSelectColumn(FeatureProductTableMap::FEATURE_AV_ID); - $criteria->addSelectColumn(FeatureProductTableMap::BY_DEFAULT); + $criteria->addSelectColumn(FeatureProductTableMap::FREE_TEXT_VALUE); $criteria->addSelectColumn(FeatureProductTableMap::POSITION); $criteria->addSelectColumn(FeatureProductTableMap::CREATED_AT); $criteria->addSelectColumn(FeatureProductTableMap::UPDATED_AT); @@ -344,7 +344,7 @@ class FeatureProductTableMap extends TableMap $criteria->addSelectColumn($alias . '.PRODUCT_ID'); $criteria->addSelectColumn($alias . '.FEATURE_ID'); $criteria->addSelectColumn($alias . '.FEATURE_AV_ID'); - $criteria->addSelectColumn($alias . '.BY_DEFAULT'); + $criteria->addSelectColumn($alias . '.FREE_TEXT_VALUE'); $criteria->addSelectColumn($alias . '.POSITION'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); diff --git a/core/lib/Thelia/Model/Map/OrderProductTableMap.php b/core/lib/Thelia/Model/Map/OrderProductTableMap.php index 038d12863..8144f23a7 100644 --- a/core/lib/Thelia/Model/Map/OrderProductTableMap.php +++ b/core/lib/Thelia/Model/Map/OrderProductTableMap.php @@ -57,7 +57,7 @@ class OrderProductTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 12; + const NUM_COLUMNS = 19; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class OrderProductTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 12; + const NUM_HYDRATE_COLUMNS = 19; /** * the column name for the ID field @@ -84,20 +84,30 @@ class OrderProductTableMap extends TableMap */ const PRODUCT_REF = 'order_product.PRODUCT_REF'; + /** + * the column name for the PRODUCT_SALE_ELEMENTS_REF field + */ + const PRODUCT_SALE_ELEMENTS_REF = 'order_product.PRODUCT_SALE_ELEMENTS_REF'; + /** * the column name for the TITLE field */ const TITLE = 'order_product.TITLE'; + /** + * the column name for the CHAPO field + */ + const CHAPO = 'order_product.CHAPO'; + /** * the column name for the DESCRIPTION field */ const DESCRIPTION = 'order_product.DESCRIPTION'; /** - * the column name for the CHAPO field + * the column name for the POSTSCRIPTUM field */ - const CHAPO = 'order_product.CHAPO'; + const POSTSCRIPTUM = 'order_product.POSTSCRIPTUM'; /** * the column name for the QUANTITY field @@ -110,9 +120,34 @@ class OrderProductTableMap extends TableMap const PRICE = 'order_product.PRICE'; /** - * the column name for the TAX field + * the column name for the PROMO_PRICE field */ - const TAX = 'order_product.TAX'; + const PROMO_PRICE = 'order_product.PROMO_PRICE'; + + /** + * the column name for the WAS_NEW field + */ + const WAS_NEW = 'order_product.WAS_NEW'; + + /** + * the column name for the WAS_IN_PROMO field + */ + const WAS_IN_PROMO = 'order_product.WAS_IN_PROMO'; + + /** + * the column name for the WEIGHT field + */ + const WEIGHT = 'order_product.WEIGHT'; + + /** + * the column name for the TAX_RULE_TITLE field + */ + const TAX_RULE_TITLE = 'order_product.TAX_RULE_TITLE'; + + /** + * the column name for the TAX_RULE_DESCRIPTION field + */ + const TAX_RULE_DESCRIPTION = 'order_product.TAX_RULE_DESCRIPTION'; /** * the column name for the PARENT field @@ -141,12 +176,12 @@ class OrderProductTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'OrderId', 'ProductRef', 'Title', 'Description', 'Chapo', 'Quantity', 'Price', 'Tax', 'Parent', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'orderId', 'productRef', 'title', 'description', 'chapo', 'quantity', 'price', 'tax', 'parent', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(OrderProductTableMap::ID, OrderProductTableMap::ORDER_ID, OrderProductTableMap::PRODUCT_REF, OrderProductTableMap::TITLE, OrderProductTableMap::DESCRIPTION, OrderProductTableMap::CHAPO, OrderProductTableMap::QUANTITY, OrderProductTableMap::PRICE, OrderProductTableMap::TAX, OrderProductTableMap::PARENT, OrderProductTableMap::CREATED_AT, OrderProductTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'ORDER_ID', 'PRODUCT_REF', 'TITLE', 'DESCRIPTION', 'CHAPO', 'QUANTITY', 'PRICE', 'TAX', 'PARENT', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'order_id', 'product_ref', 'title', 'description', 'chapo', 'quantity', 'price', 'tax', 'parent', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) + self::TYPE_PHPNAME => array('Id', 'OrderId', 'ProductRef', 'ProductSaleElementsRef', 'Title', 'Chapo', 'Description', 'Postscriptum', 'Quantity', 'Price', 'PromoPrice', 'WasNew', 'WasInPromo', 'Weight', 'TaxRuleTitle', 'TaxRuleDescription', 'Parent', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'orderId', 'productRef', 'productSaleElementsRef', 'title', 'chapo', 'description', 'postscriptum', 'quantity', 'price', 'promoPrice', 'wasNew', 'wasInPromo', 'weight', 'taxRuleTitle', 'taxRuleDescription', 'parent', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(OrderProductTableMap::ID, OrderProductTableMap::ORDER_ID, OrderProductTableMap::PRODUCT_REF, OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF, OrderProductTableMap::TITLE, OrderProductTableMap::CHAPO, OrderProductTableMap::DESCRIPTION, OrderProductTableMap::POSTSCRIPTUM, OrderProductTableMap::QUANTITY, OrderProductTableMap::PRICE, OrderProductTableMap::PROMO_PRICE, OrderProductTableMap::WAS_NEW, OrderProductTableMap::WAS_IN_PROMO, OrderProductTableMap::WEIGHT, OrderProductTableMap::TAX_RULE_TITLE, OrderProductTableMap::TAX_RULE_DESCRIPTION, OrderProductTableMap::PARENT, OrderProductTableMap::CREATED_AT, OrderProductTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'ORDER_ID', 'PRODUCT_REF', 'PRODUCT_SALE_ELEMENTS_REF', 'TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM', 'QUANTITY', 'PRICE', 'PROMO_PRICE', 'WAS_NEW', 'WAS_IN_PROMO', 'WEIGHT', 'TAX_RULE_TITLE', 'TAX_RULE_DESCRIPTION', 'PARENT', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'order_id', 'product_ref', 'product_sale_elements_ref', 'title', 'chapo', 'description', 'postscriptum', 'quantity', 'price', 'promo_price', 'was_new', 'was_in_promo', 'weight', 'tax_rule_title', 'tax_rule_description', 'parent', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ) ); /** @@ -156,12 +191,12 @@ class OrderProductTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'OrderId' => 1, 'ProductRef' => 2, 'Title' => 3, 'Description' => 4, 'Chapo' => 5, 'Quantity' => 6, 'Price' => 7, 'Tax' => 8, 'Parent' => 9, 'CreatedAt' => 10, 'UpdatedAt' => 11, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'orderId' => 1, 'productRef' => 2, 'title' => 3, 'description' => 4, 'chapo' => 5, 'quantity' => 6, 'price' => 7, 'tax' => 8, 'parent' => 9, 'createdAt' => 10, 'updatedAt' => 11, ), - self::TYPE_COLNAME => array(OrderProductTableMap::ID => 0, OrderProductTableMap::ORDER_ID => 1, OrderProductTableMap::PRODUCT_REF => 2, OrderProductTableMap::TITLE => 3, OrderProductTableMap::DESCRIPTION => 4, OrderProductTableMap::CHAPO => 5, OrderProductTableMap::QUANTITY => 6, OrderProductTableMap::PRICE => 7, OrderProductTableMap::TAX => 8, OrderProductTableMap::PARENT => 9, OrderProductTableMap::CREATED_AT => 10, OrderProductTableMap::UPDATED_AT => 11, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'ORDER_ID' => 1, 'PRODUCT_REF' => 2, 'TITLE' => 3, 'DESCRIPTION' => 4, 'CHAPO' => 5, 'QUANTITY' => 6, 'PRICE' => 7, 'TAX' => 8, 'PARENT' => 9, 'CREATED_AT' => 10, 'UPDATED_AT' => 11, ), - self::TYPE_FIELDNAME => array('id' => 0, 'order_id' => 1, 'product_ref' => 2, 'title' => 3, 'description' => 4, 'chapo' => 5, 'quantity' => 6, 'price' => 7, 'tax' => 8, 'parent' => 9, 'created_at' => 10, 'updated_at' => 11, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) + self::TYPE_PHPNAME => array('Id' => 0, 'OrderId' => 1, 'ProductRef' => 2, 'ProductSaleElementsRef' => 3, 'Title' => 4, 'Chapo' => 5, 'Description' => 6, 'Postscriptum' => 7, 'Quantity' => 8, 'Price' => 9, 'PromoPrice' => 10, 'WasNew' => 11, 'WasInPromo' => 12, 'Weight' => 13, 'TaxRuleTitle' => 14, 'TaxRuleDescription' => 15, 'Parent' => 16, 'CreatedAt' => 17, 'UpdatedAt' => 18, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'orderId' => 1, 'productRef' => 2, 'productSaleElementsRef' => 3, 'title' => 4, 'chapo' => 5, 'description' => 6, 'postscriptum' => 7, 'quantity' => 8, 'price' => 9, 'promoPrice' => 10, 'wasNew' => 11, 'wasInPromo' => 12, 'weight' => 13, 'taxRuleTitle' => 14, 'taxRuleDescription' => 15, 'parent' => 16, 'createdAt' => 17, 'updatedAt' => 18, ), + self::TYPE_COLNAME => array(OrderProductTableMap::ID => 0, OrderProductTableMap::ORDER_ID => 1, OrderProductTableMap::PRODUCT_REF => 2, OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF => 3, OrderProductTableMap::TITLE => 4, OrderProductTableMap::CHAPO => 5, OrderProductTableMap::DESCRIPTION => 6, OrderProductTableMap::POSTSCRIPTUM => 7, OrderProductTableMap::QUANTITY => 8, OrderProductTableMap::PRICE => 9, OrderProductTableMap::PROMO_PRICE => 10, OrderProductTableMap::WAS_NEW => 11, OrderProductTableMap::WAS_IN_PROMO => 12, OrderProductTableMap::WEIGHT => 13, OrderProductTableMap::TAX_RULE_TITLE => 14, OrderProductTableMap::TAX_RULE_DESCRIPTION => 15, OrderProductTableMap::PARENT => 16, OrderProductTableMap::CREATED_AT => 17, OrderProductTableMap::UPDATED_AT => 18, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'ORDER_ID' => 1, 'PRODUCT_REF' => 2, 'PRODUCT_SALE_ELEMENTS_REF' => 3, 'TITLE' => 4, 'CHAPO' => 5, 'DESCRIPTION' => 6, 'POSTSCRIPTUM' => 7, 'QUANTITY' => 8, 'PRICE' => 9, 'PROMO_PRICE' => 10, 'WAS_NEW' => 11, 'WAS_IN_PROMO' => 12, 'WEIGHT' => 13, 'TAX_RULE_TITLE' => 14, 'TAX_RULE_DESCRIPTION' => 15, 'PARENT' => 16, 'CREATED_AT' => 17, 'UPDATED_AT' => 18, ), + self::TYPE_FIELDNAME => array('id' => 0, 'order_id' => 1, 'product_ref' => 2, 'product_sale_elements_ref' => 3, 'title' => 4, 'chapo' => 5, 'description' => 6, 'postscriptum' => 7, 'quantity' => 8, 'price' => 9, 'promo_price' => 10, 'was_new' => 11, 'was_in_promo' => 12, 'weight' => 13, 'tax_rule_title' => 14, 'tax_rule_description' => 15, 'parent' => 16, 'created_at' => 17, 'updated_at' => 18, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ) ); /** @@ -182,13 +217,20 @@ class OrderProductTableMap extends TableMap // columns $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); $this->addForeignKey('ORDER_ID', 'OrderId', 'INTEGER', 'order', 'ID', true, null, null); - $this->addColumn('PRODUCT_REF', 'ProductRef', 'VARCHAR', false, 255, null); + $this->addColumn('PRODUCT_REF', 'ProductRef', 'VARCHAR', true, 255, null); + $this->addColumn('PRODUCT_SALE_ELEMENTS_REF', 'ProductSaleElementsRef', 'VARCHAR', true, 255, null); $this->addColumn('TITLE', 'Title', 'VARCHAR', false, 255, null); - $this->addColumn('DESCRIPTION', 'Description', 'LONGVARCHAR', false, null, null); $this->addColumn('CHAPO', 'Chapo', 'LONGVARCHAR', false, null, null); + $this->addColumn('DESCRIPTION', 'Description', 'CLOB', false, null, null); + $this->addColumn('POSTSCRIPTUM', 'Postscriptum', 'LONGVARCHAR', false, null, null); $this->addColumn('QUANTITY', 'Quantity', 'FLOAT', true, null, null); $this->addColumn('PRICE', 'Price', 'FLOAT', true, null, null); - $this->addColumn('TAX', 'Tax', 'FLOAT', false, null, null); + $this->addColumn('PROMO_PRICE', 'PromoPrice', 'VARCHAR', false, 45, null); + $this->addColumn('WAS_NEW', 'WasNew', 'TINYINT', true, null, null); + $this->addColumn('WAS_IN_PROMO', 'WasInPromo', 'TINYINT', true, null, null); + $this->addColumn('WEIGHT', 'Weight', 'VARCHAR', false, 45, null); + $this->addColumn('TAX_RULE_TITLE', 'TaxRuleTitle', 'VARCHAR', false, 255, null); + $this->addColumn('TAX_RULE_DESCRIPTION', 'TaxRuleDescription', 'CLOB', false, null, null); $this->addColumn('PARENT', 'Parent', 'INTEGER', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); @@ -200,7 +242,8 @@ class OrderProductTableMap extends TableMap public function buildRelations() { $this->addRelation('Order', '\\Thelia\\Model\\Order', RelationMap::MANY_TO_ONE, array('order_id' => 'id', ), 'CASCADE', 'RESTRICT'); - $this->addRelation('OrderFeature', '\\Thelia\\Model\\OrderFeature', RelationMap::ONE_TO_MANY, array('id' => 'order_product_id', ), 'CASCADE', 'RESTRICT', 'OrderFeatures'); + $this->addRelation('OrderProductAttributeCombination', '\\Thelia\\Model\\OrderProductAttributeCombination', RelationMap::ONE_TO_MANY, array('id' => 'order_product_id', ), 'CASCADE', 'RESTRICT', 'OrderProductAttributeCombinations'); + $this->addRelation('OrderProductTax', '\\Thelia\\Model\\OrderProductTax', RelationMap::ONE_TO_MANY, array('id' => 'order_product_id', ), 'CASCADE', 'RESTRICT', 'OrderProductTaxes'); } // buildRelations() /** @@ -222,7 +265,8 @@ class OrderProductTableMap 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. - OrderFeatureTableMap::clearInstancePool(); + OrderProductAttributeCombinationTableMap::clearInstancePool(); + OrderProductTaxTableMap::clearInstancePool(); } /** @@ -366,12 +410,19 @@ class OrderProductTableMap extends TableMap $criteria->addSelectColumn(OrderProductTableMap::ID); $criteria->addSelectColumn(OrderProductTableMap::ORDER_ID); $criteria->addSelectColumn(OrderProductTableMap::PRODUCT_REF); + $criteria->addSelectColumn(OrderProductTableMap::PRODUCT_SALE_ELEMENTS_REF); $criteria->addSelectColumn(OrderProductTableMap::TITLE); - $criteria->addSelectColumn(OrderProductTableMap::DESCRIPTION); $criteria->addSelectColumn(OrderProductTableMap::CHAPO); + $criteria->addSelectColumn(OrderProductTableMap::DESCRIPTION); + $criteria->addSelectColumn(OrderProductTableMap::POSTSCRIPTUM); $criteria->addSelectColumn(OrderProductTableMap::QUANTITY); $criteria->addSelectColumn(OrderProductTableMap::PRICE); - $criteria->addSelectColumn(OrderProductTableMap::TAX); + $criteria->addSelectColumn(OrderProductTableMap::PROMO_PRICE); + $criteria->addSelectColumn(OrderProductTableMap::WAS_NEW); + $criteria->addSelectColumn(OrderProductTableMap::WAS_IN_PROMO); + $criteria->addSelectColumn(OrderProductTableMap::WEIGHT); + $criteria->addSelectColumn(OrderProductTableMap::TAX_RULE_TITLE); + $criteria->addSelectColumn(OrderProductTableMap::TAX_RULE_DESCRIPTION); $criteria->addSelectColumn(OrderProductTableMap::PARENT); $criteria->addSelectColumn(OrderProductTableMap::CREATED_AT); $criteria->addSelectColumn(OrderProductTableMap::UPDATED_AT); @@ -379,12 +430,19 @@ class OrderProductTableMap extends TableMap $criteria->addSelectColumn($alias . '.ID'); $criteria->addSelectColumn($alias . '.ORDER_ID'); $criteria->addSelectColumn($alias . '.PRODUCT_REF'); + $criteria->addSelectColumn($alias . '.PRODUCT_SALE_ELEMENTS_REF'); $criteria->addSelectColumn($alias . '.TITLE'); - $criteria->addSelectColumn($alias . '.DESCRIPTION'); $criteria->addSelectColumn($alias . '.CHAPO'); + $criteria->addSelectColumn($alias . '.DESCRIPTION'); + $criteria->addSelectColumn($alias . '.POSTSCRIPTUM'); $criteria->addSelectColumn($alias . '.QUANTITY'); $criteria->addSelectColumn($alias . '.PRICE'); - $criteria->addSelectColumn($alias . '.TAX'); + $criteria->addSelectColumn($alias . '.PROMO_PRICE'); + $criteria->addSelectColumn($alias . '.WAS_NEW'); + $criteria->addSelectColumn($alias . '.WAS_IN_PROMO'); + $criteria->addSelectColumn($alias . '.WEIGHT'); + $criteria->addSelectColumn($alias . '.TAX_RULE_TITLE'); + $criteria->addSelectColumn($alias . '.TAX_RULE_DESCRIPTION'); $criteria->addSelectColumn($alias . '.PARENT'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); diff --git a/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php b/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php index fc23ae569..70b3819f9 100644 --- a/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php +++ b/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php @@ -167,7 +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('REF', 'Ref', 'VARCHAR', true, 255, 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); diff --git a/core/lib/Thelia/Model/Map/TaxI18nTableMap.php b/core/lib/Thelia/Model/Map/TaxI18nTableMap.php index a06230c37..c50a30c90 100644 --- a/core/lib/Thelia/Model/Map/TaxI18nTableMap.php +++ b/core/lib/Thelia/Model/Map/TaxI18nTableMap.php @@ -143,7 +143,7 @@ class TaxI18nTableMap extends TableMap $this->addForeignPrimaryKey('ID', 'Id', 'INTEGER' , 'tax', 'ID', true, null, null); $this->addPrimaryKey('LOCALE', 'Locale', 'VARCHAR', true, 5, 'en_US'); $this->addColumn('TITLE', 'Title', 'VARCHAR', false, 255, null); - $this->addColumn('DESCRIPTION', 'Description', 'LONGVARCHAR', false, null, null); + $this->addColumn('DESCRIPTION', 'Description', 'CLOB', false, null, null); } // initialize() /** diff --git a/core/lib/Thelia/Model/Map/TaxRuleI18nTableMap.php b/core/lib/Thelia/Model/Map/TaxRuleI18nTableMap.php index 012ad2e72..24f8a41d7 100644 --- a/core/lib/Thelia/Model/Map/TaxRuleI18nTableMap.php +++ b/core/lib/Thelia/Model/Map/TaxRuleI18nTableMap.php @@ -143,7 +143,7 @@ class TaxRuleI18nTableMap extends TableMap $this->addForeignPrimaryKey('ID', 'Id', 'INTEGER' , 'tax_rule', 'ID', true, null, null); $this->addPrimaryKey('LOCALE', 'Locale', 'VARCHAR', true, 5, 'en_US'); $this->addColumn('TITLE', 'Title', 'VARCHAR', false, 255, null); - $this->addColumn('DESCRIPTION', 'Description', 'LONGVARCHAR', false, null, null); + $this->addColumn('DESCRIPTION', 'Description', 'CLOB', false, null, null); } // initialize() /** diff --git a/install/faker.php b/install/faker.php index eed6db11a..2c82f5d1b 100755 --- a/install/faker.php +++ b/install/faker.php @@ -442,7 +442,7 @@ try { $featureAvId[array_rand($featureAvId, 1)] ); } else { //no av - $featureProduct->setByDefault($faker->text(10)); + $featureProduct->setFreeTextValue($faker->text(10)); } $featureProduct->save(); diff --git a/install/thelia.sql b/install/thelia.sql index bd983d26d..efa72b629 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -51,7 +51,7 @@ CREATE TABLE `product` REFERENCES `tax_rule` (`id`) ON UPDATE RESTRICT ON DELETE SET NULL, - CONSTRAINT `fk_product_template1` + CONSTRAINT `fk_product_template` FOREIGN KEY (`template_id`) REFERENCES `template` (`id`) ) ENGINE=InnoDB; @@ -226,7 +226,7 @@ CREATE TABLE `feature_product` `product_id` INTEGER NOT NULL, `feature_id` INTEGER NOT NULL, `feature_av_id` INTEGER, - `by_default` VARCHAR(255), + `free_text_value` TEXT, `position` INTEGER, `created_at` DATETIME, `updated_at` DATETIME, @@ -325,6 +325,7 @@ CREATE TABLE `attribute_combination` `attribute_id` INTEGER NOT NULL, `attribute_av_id` INTEGER NOT NULL, `product_sale_elements_id` INTEGER NOT NULL, + `is_default` TINYINT(1) DEFAULT 0, `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`attribute_id`,`attribute_av_id`,`product_sale_elements_id`), @@ -358,7 +359,7 @@ CREATE TABLE `product_sale_elements` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `product_id` INTEGER NOT NULL, - `ref` VARCHAR(45) NOT NULL, + `ref` VARCHAR(255) NOT NULL, `quantity` FLOAT NOT NULL, `promo` TINYINT DEFAULT 0, `newness` TINYINT DEFAULT 0, @@ -760,14 +761,21 @@ CREATE TABLE `order_product` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `order_id` INTEGER NOT NULL, - `product_ref` VARCHAR(255), + `product_ref` VARCHAR(255) NOT NULL, + `product_sale_elements_ref` VARCHAR(255) NOT NULL, `title` VARCHAR(255), - `description` TEXT, `chapo` TEXT, + `description` LONGTEXT, + `postscriptum` TEXT, `quantity` FLOAT NOT NULL, `price` FLOAT NOT NULL, - `tax` FLOAT, - `parent` INTEGER, + `promo_price` VARCHAR(45), + `was_new` TINYINT NOT NULL, + `was_in_promo` TINYINT NOT NULL, + `weight` VARCHAR(45), + `tax_rule_title` VARCHAR(255), + `tax_rule_description` LONGTEXT, + `parent` INTEGER COMMENT 'not managed yet', `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), @@ -796,22 +804,28 @@ CREATE TABLE `order_status` ) ENGINE=InnoDB; -- --------------------------------------------------------------------- --- order_feature +-- order_product_attribute_combination -- --------------------------------------------------------------------- -DROP TABLE IF EXISTS `order_feature`; +DROP TABLE IF EXISTS `order_product_attribute_combination`; -CREATE TABLE `order_feature` +CREATE TABLE `order_product_attribute_combination` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `order_product_id` INTEGER NOT NULL, - `feature_desc` VARCHAR(255), - `feature_av_desc` VARCHAR(255), + `attribute_title` VARCHAR(255) NOT NULL, + `attribute_chapo` TEXT, + `attribute_description` LONGTEXT, + `attribute_postscriptumn` TEXT, + `attribute_av_title` VARCHAR(255) NOT NULL, + `attribute_av_chapo` TEXT, + `attribute_av_description` LONGTEXT, + `attribute_av_postscriptum` TEXT, `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), - INDEX `idx_order_feature_order_product_id` (`order_product_id`), - CONSTRAINT `fk_order_feature_order_product_id` + INDEX `idx_order_product_attribute_combination_order_product_id` (`order_product_id`), + CONSTRAINT `fk_order_product_attribute_combination_order_product_id` FOREIGN KEY (`order_product_id`) REFERENCES `order_product` (`id`) ON UPDATE RESTRICT @@ -1560,6 +1574,30 @@ CREATE TABLE `module_image` ON DELETE CASCADE ) ENGINE=InnoDB; +-- --------------------------------------------------------------------- +-- order_product_tax +-- --------------------------------------------------------------------- + +DROP TABLE IF EXISTS `order_product_tax`; + +CREATE TABLE `order_product_tax` +( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `order_product_id` INTEGER NOT NULL, + `title` VARCHAR(255) NOT NULL, + `description` LONGTEXT, + `amount` FLOAT NOT NULL, + `created_at` DATETIME, + `updated_at` DATETIME, + PRIMARY KEY (`id`), + INDEX `idx_ order_product_tax_order_product_id` (`order_product_id`), + CONSTRAINT `fk_ order_product_tax_order_product_id0` + FOREIGN KEY (`order_product_id`) + REFERENCES `order_product` (`id`) + ON UPDATE RESTRICT + ON DELETE CASCADE +) ENGINE=InnoDB; + -- --------------------------------------------------------------------- -- category_i18n -- --------------------------------------------------------------------- @@ -1634,7 +1672,7 @@ CREATE TABLE `tax_i18n` `id` INTEGER NOT NULL, `locale` VARCHAR(5) DEFAULT 'en_US' NOT NULL, `title` VARCHAR(255), - `description` TEXT, + `description` LONGTEXT, PRIMARY KEY (`id`,`locale`), CONSTRAINT `tax_i18n_FK_1` FOREIGN KEY (`id`) @@ -1653,7 +1691,7 @@ CREATE TABLE `tax_rule_i18n` `id` INTEGER NOT NULL, `locale` VARCHAR(5) DEFAULT 'en_US' NOT NULL, `title` VARCHAR(255), - `description` TEXT, + `description` LONGTEXT, PRIMARY KEY (`id`,`locale`), CONSTRAINT `tax_rule_i18n_FK_1` FOREIGN KEY (`id`) diff --git a/local/config/schema.xml b/local/config/schema.xml index b767580ef..98cf32ffb 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -1,1227 +1,1255 @@ - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - -
- - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
- - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
- - - - - - - -
- - - - - - - - - - - - - - - - - - - -
-
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+
diff --git a/templates/admin/default/ajax/template-attribute-list.html b/templates/admin/default/ajax/template-attribute-list.html index a630aaa61..7276e6005 100644 --- a/templates/admin/default/ajax/template-attribute-list.html +++ b/templates/admin/default/ajax/template-attribute-list.html @@ -6,7 +6,7 @@
- + {loop name="free_features" type="feature" exclude_template="$template_id" backend_context="1" lang="$edit_language_id"} {/loop} diff --git a/templates/admin/default/category-edit.html b/templates/admin/default/category-edit.html index b974a4564..63dbbfdb1 100755 --- a/templates/admin/default/category-edit.html +++ b/templates/admin/default/category-edit.html @@ -163,7 +163,7 @@
- + diff --git a/templates/admin/default/feature-edit.html b/templates/admin/default/feature-edit.html index a21c63f61..41a6276b9 100644 --- a/templates/admin/default/feature-edit.html +++ b/templates/admin/default/feature-edit.html @@ -1,6 +1,6 @@ {extends file="admin-layout.tpl"} -{block name="page-title"}{intl l='Edit an feature'}{/block} +{block name="page-title"}{intl l='Edit a feature'}{/block} {block name="check-permissions"}admin.configuration.features.edit{/block} @@ -75,9 +75,9 @@

- {intl l="Enter here all possible feature values."} + {intl l="Enter here all possible feature values. To get a free text feature in product forms, don't add any value."}
- +
@@ -122,7 +122,7 @@ - {loop name="list" type="feature_availability" feature=$feature_id backend_context="1" lang=$edit_language_id order=$featureav_order} + {loop name="list" type="feature-availability" feature=$feature_id backend_context="1" lang=$edit_language_id order=$featureav_order} diff --git a/templates/admin/default/folder-edit.html b/templates/admin/default/folder-edit.html index 6986a1e69..cfe835ef5 100644 --- a/templates/admin/default/folder-edit.html +++ b/templates/admin/default/folder-edit.html @@ -161,7 +161,7 @@
- + diff --git a/templates/admin/default/includes/standard-description-form-fields.html b/templates/admin/default/includes/standard-description-form-fields.html index 17c340b27..ca78324ad 100644 --- a/templates/admin/default/includes/standard-description-form-fields.html +++ b/templates/admin/default/includes/standard-description-form-fields.html @@ -22,7 +22,7 @@
diff --git a/templates/admin/default/product-edit.html b/templates/admin/default/product-edit.html index d80d9ca0a..4464e0071 100644 --- a/templates/admin/default/product-edit.html +++ b/templates/admin/default/product-edit.html @@ -41,7 +41,8 @@
{$ID}
- - - - - - - {module_include location='product_contents_table_header'} - - - - - - - {loop name="assigned_contents" type="associated_content" product="$product_id" backend_context="1" lang="$edit_language_id"} - - - - - - {module_include location='product_contents_table_row'} - - - - {/loop} - - {elseloop rel="assigned_contents"} - - - - {/elseloop} - -
{intl l='ID'}{intl l='Content title'}{intl l="Actions"}
{$ID} - {$TITLE} - -
- {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.product.content.delete"} - - - - {/loop} -
-
-
- {intl l="This product contains no contents"} -
-
-
- - {* -- End related content management ---- *} - - {* -- Begin accessories management ------ *} - -
-
-
- -

{intl l='Product accessories'}

-

{intl l='Define here this product\'s accessories'}

- - - - - {ifloop rel="categories"} -
- - - {intl l='Select a category to get its products'} -
- -
-
- - - - -
- - {intl l='Select a product and click (+) to add it as an accessory'} -
- -
-
- {intl l="No available product in this category"} -
-
- - {/ifloop} - - {elseloop rel="categories"} -
{intl l="No categories found"}
- {/elseloop} - -
-
- - - - - - - - - - - {module_include location='product_accessories_table_header'} - - - - - - - {loop name="assigned_accessories" order="accessory" type="accessory" product="$product_id" backend_context="1" lang="$edit_language_id"} - - - - - - - - {module_include location='product_accessories_table_row'} - - - - {/loop} - - {elseloop rel="assigned_accessories"} - - - - {/elseloop} - -
{intl l='ID'}{intl l='Accessory title'}{intl l='Position'}{intl l="Actions"}
{$ID} - {$TITLE} - - {admin_position_block - permission="admin.products.edit" - path={url path='/admin/products/update-accessory-position' product_id=$ID} - url_parameter="accessory_id" - in_place_edit_class="accessoryPositionChange" - position=$POSITION - id=$ID - } - -
- {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.product.accessory.delete"} - - - - {/loop} -
-
-
- {intl l="This product contains no accessories"} -
-
-
- - {* -- End accessories management -------- *} - -
@@ -397,48 +85,6 @@
- -{* Delete related content confirmation dialog *} - -{capture "delete_content_dialog"} - - - - - -{/capture} - -{include - file = "includes/generic-confirm-dialog.html" - - dialog_id = "delete_content_dialog" - dialog_title = {intl l="Remove related content"} - dialog_message = {intl l="Do you really want to remove this related content from the product ?"} - - form_action = {url path='/admin/products/related-content/delete'} - form_content = {$smarty.capture.delete_content_dialog nofilter} -} - -{* Delete accessory confirmation dialog *} - -{capture "delete_accessory_dialog"} - - - - - -{/capture} - -{include - file = "includes/generic-confirm-dialog.html" - - dialog_id = "delete_accessory_dialog" - dialog_title = {intl l="Remove an accessory"} - dialog_message = {intl l="Do you really want to remove this accessory from the product ?"} - - form_action = {url path='/admin/products/accessory/delete'} - form_content = {$smarty.capture.delete_accessory_dialog nofilter} -} {/block} {block name="javascript-initialization"} @@ -594,6 +240,13 @@ $(function() { {if $accessory_category_id != 0} $('#accessory_category_id').val("{$accessory_category_id}").change(); {/if} + + // Unselect all options in attribute + feature tab + $('.clear_feature_value').click(function(event){ + $('#feature_value_' + $(this).data('id') + ' option').prop('selected', false); + + event.preventDefault(); + }); }); {/block} \ No newline at end of file From 5622a246b2eada6fd7da7ca70f791e6140aa0614 Mon Sep 17 00:00:00 2001 From: franck Date: Fri, 20 Sep 2013 15:59:19 +0200 Subject: [PATCH 03/43] Added missing files --- .../Controller/Admin/ProductController.php | 1 + .../Core/Event/FeatureProductDeleteEvent.php | 61 + .../Thelia/Core/Event/FeatureProductEvent.php | 52 + .../Core/Event/FeatureProductUpdateEvent.php | 89 + .../Core/Template/Loop/FeatureValue.php | 17 +- .../Base/OrderProductAttributeCombination.php | 1824 +++++++++++++++++ .../OrderProductAttributeCombinationQuery.php | 897 ++++++++ .../lib/Thelia/Model/Base/OrderProductTax.php | 1534 ++++++++++++++ .../Model/Base/OrderProductTaxQuery.php | 744 +++++++ ...derProductAttributeCombinationTableMap.php | 503 +++++ .../Model/Map/OrderProductTaxTableMap.php | 463 +++++ .../OrderProductAttributeCombination.php | 10 + .../OrderProductAttributeCombinationQuery.php | 21 + core/lib/Thelia/Model/OrderProductTax.php | 10 + .../lib/Thelia/Model/OrderProductTaxQuery.php | 21 + .../includes/product-attributes-tab.html | 158 ++ .../default/includes/product-content-tab.html | 273 +++ .../default/includes/product-general-tab.html | 97 + 18 files changed, 6767 insertions(+), 8 deletions(-) create mode 100644 core/lib/Thelia/Core/Event/FeatureProductDeleteEvent.php create mode 100644 core/lib/Thelia/Core/Event/FeatureProductEvent.php create mode 100644 core/lib/Thelia/Core/Event/FeatureProductUpdateEvent.php create mode 100644 core/lib/Thelia/Model/Base/OrderProductAttributeCombination.php create mode 100644 core/lib/Thelia/Model/Base/OrderProductAttributeCombinationQuery.php create mode 100644 core/lib/Thelia/Model/Base/OrderProductTax.php create mode 100644 core/lib/Thelia/Model/Base/OrderProductTaxQuery.php create mode 100644 core/lib/Thelia/Model/Map/OrderProductAttributeCombinationTableMap.php create mode 100644 core/lib/Thelia/Model/Map/OrderProductTaxTableMap.php create mode 100644 core/lib/Thelia/Model/OrderProductAttributeCombination.php create mode 100644 core/lib/Thelia/Model/OrderProductAttributeCombinationQuery.php create mode 100644 core/lib/Thelia/Model/OrderProductTax.php create mode 100644 core/lib/Thelia/Model/OrderProductTaxQuery.php create mode 100644 templates/admin/default/includes/product-attributes-tab.html create mode 100644 templates/admin/default/includes/product-content-tab.html create mode 100644 templates/admin/default/includes/product-general-tab.html diff --git a/core/lib/Thelia/Controller/Admin/ProductController.php b/core/lib/Thelia/Controller/Admin/ProductController.php index cefed04ff..f3c4cb136 100644 --- a/core/lib/Thelia/Controller/Admin/ProductController.php +++ b/core/lib/Thelia/Controller/Admin/ProductController.php @@ -542,6 +542,7 @@ echo "delete $productId, ".$feature->getId()." - "; } } } +exit; } $this->redirectToEditionTemplate(); diff --git a/core/lib/Thelia/Core/Event/FeatureProductDeleteEvent.php b/core/lib/Thelia/Core/Event/FeatureProductDeleteEvent.php new file mode 100644 index 000000000..5c74c6287 --- /dev/null +++ b/core/lib/Thelia/Core/Event/FeatureProductDeleteEvent.php @@ -0,0 +1,61 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; +use Thelia\Model\FeatureProduct; + +class FeatureProductDeleteEvent extends FeatureProductEvent +{ + protected $product_id; + protected $feature_id; + + public function __construct($product_id, $feature_id) + { + $this->product_id = $product_id; + $this->feature_id = $feature_id; + } + + public function getProductId() + { + return $this->product_id; + } + + public function setProductId($product_id) + { + $this->product_id = $product_id; + + return $this; + } + + public function getFeatureId() + { + return $this->feature_id; + } + + public function setFeatureId($feature_id) + { + $this->feature_id = $feature_id; + + return $this; + } +} diff --git a/core/lib/Thelia/Core/Event/FeatureProductEvent.php b/core/lib/Thelia/Core/Event/FeatureProductEvent.php new file mode 100644 index 000000000..0acf48569 --- /dev/null +++ b/core/lib/Thelia/Core/Event/FeatureProductEvent.php @@ -0,0 +1,52 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; +use Thelia\Model\FeatureProduct; + +class FeatureProductEvent extends ActionEvent +{ + protected $featureProduct = null; + + public function __construct(FeatureProduct $featureProduct = null) + { + $this->featureProduct = $featureProduct; + } + + public function hasFeatureProduct() + { + return ! is_null($this->featureProduct); + } + + public function getFeatureProduct() + { + return $this->featureProduct; + } + + public function setFeatureProduct($featureProduct) + { + $this->featureProduct = $featureProduct; + + return $this; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/FeatureProductUpdateEvent.php b/core/lib/Thelia/Core/Event/FeatureProductUpdateEvent.php new file mode 100644 index 000000000..5493c55a7 --- /dev/null +++ b/core/lib/Thelia/Core/Event/FeatureProductUpdateEvent.php @@ -0,0 +1,89 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; +use Thelia\Model\FeatureProduct; + +class FeatureProductUpdateEvent extends FeatureProductEvent +{ + protected $product_id; + protected $feature_id; + protected $feature_value; + protected $is_text_value; + + public function __construct($product_id, $feature_id, $feature_value, $is_text_value = false) + { + $this->product_id = $product_id; + $this->feature_id = $feature_id; + $this->feature_value = $feature_value; + $this->is_text_value = $is_text_value; + } + + public function getProductId() + { + return $this->product_id; + } + + public function setProductId($product_id) + { + $this->product_id = $product_id; + + return $this; + } + + public function getFeatureId() + { + return $this->feature_id; + } + + public function setFeatureId($feature_id) + { + $this->feature_id = $feature_id; + + return $this; + } + + public function getFeatureValue() + { + return $this->feature_value; + } + + public function setFeatureValue($feature_value) + { + $this->feature_value = $feature_value; + + return $this; + } + + public function getIsTextValue() + { + return $this->is_text_value; + } + + public function setIsTextValue($is_text_value) + { + $this->is_text_value = $is_text_value; + + return $this; + } +} diff --git a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php index eaa81153b..8ae8b0f4f 100755 --- a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php +++ b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php @@ -79,14 +79,14 @@ class FeatureValue extends BaseI18nLoop { $search = FeatureProductQuery::create(); - // manage featureAv translations - $locale = $this->configureI18nProcessing( - $search, - array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), - FeatureAvTableMap::TABLE_NAME, - 'FEATURE_AV_ID', - true - ); + // manage featureAv translations + $locale = $this->configureI18nProcessing( + $search, + array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), + FeatureAvTableMap::TABLE_NAME, + 'FEATURE_AV_ID', + true + ); $feature = $this->getFeature(); @@ -132,6 +132,7 @@ class FeatureValue extends BaseI18nLoop $loopResult = new LoopResult($featureValues); foreach ($featureValues as $featureValue) { + $loopResultRow = new LoopResultRow($loopResult, $featureValue, $this->versionable, $this->timestampable, $this->countable); $loopResultRow diff --git a/core/lib/Thelia/Model/Base/OrderProductAttributeCombination.php b/core/lib/Thelia/Model/Base/OrderProductAttributeCombination.php new file mode 100644 index 000000000..e02bc9cc5 --- /dev/null +++ b/core/lib/Thelia/Model/Base/OrderProductAttributeCombination.php @@ -0,0 +1,1824 @@ +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 OrderProductAttributeCombination instance. If + * obj is an instance of OrderProductAttributeCombination, delegates to + * equals(OrderProductAttributeCombination). 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 OrderProductAttributeCombination 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 OrderProductAttributeCombination 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 [order_product_id] column value. + * + * @return int + */ + public function getOrderProductId() + { + + return $this->order_product_id; + } + + /** + * Get the [attribute_title] column value. + * + * @return string + */ + public function getAttributeTitle() + { + + return $this->attribute_title; + } + + /** + * Get the [attribute_chapo] column value. + * + * @return string + */ + public function getAttributeChapo() + { + + return $this->attribute_chapo; + } + + /** + * Get the [attribute_description] column value. + * + * @return string + */ + public function getAttributeDescription() + { + + return $this->attribute_description; + } + + /** + * Get the [attribute_postscriptumn] column value. + * + * @return string + */ + public function getAttributePostscriptumn() + { + + return $this->attribute_postscriptumn; + } + + /** + * Get the [attribute_av_title] column value. + * + * @return string + */ + public function getAttributeAvTitle() + { + + return $this->attribute_av_title; + } + + /** + * Get the [attribute_av_chapo] column value. + * + * @return string + */ + public function getAttributeAvChapo() + { + + return $this->attribute_av_chapo; + } + + /** + * Get the [attribute_av_description] column value. + * + * @return string + */ + public function getAttributeAvDescription() + { + + return $this->attribute_av_description; + } + + /** + * Get the [attribute_av_postscriptum] column value. + * + * @return string + */ + public function getAttributeAvPostscriptum() + { + + return $this->attribute_av_postscriptum; + } + + /** + * 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\OrderProductAttributeCombination 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[] = OrderProductAttributeCombinationTableMap::ID; + } + + + return $this; + } // setId() + + /** + * Set the value of [order_product_id] column. + * + * @param int $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setOrderProductId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->order_product_id !== $v) { + $this->order_product_id = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID; + } + + if ($this->aOrderProduct !== null && $this->aOrderProduct->getId() !== $v) { + $this->aOrderProduct = null; + } + + + return $this; + } // setOrderProductId() + + /** + * Set the value of [attribute_title] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributeTitle($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_title !== $v) { + $this->attribute_title = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE; + } + + + return $this; + } // setAttributeTitle() + + /** + * Set the value of [attribute_chapo] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributeChapo($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_chapo !== $v) { + $this->attribute_chapo = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO; + } + + + return $this; + } // setAttributeChapo() + + /** + * Set the value of [attribute_description] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributeDescription($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_description !== $v) { + $this->attribute_description = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION; + } + + + return $this; + } // setAttributeDescription() + + /** + * Set the value of [attribute_postscriptumn] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributePostscriptumn($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_postscriptumn !== $v) { + $this->attribute_postscriptumn = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN; + } + + + return $this; + } // setAttributePostscriptumn() + + /** + * Set the value of [attribute_av_title] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributeAvTitle($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_av_title !== $v) { + $this->attribute_av_title = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE; + } + + + return $this; + } // setAttributeAvTitle() + + /** + * Set the value of [attribute_av_chapo] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributeAvChapo($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_av_chapo !== $v) { + $this->attribute_av_chapo = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO; + } + + + return $this; + } // setAttributeAvChapo() + + /** + * Set the value of [attribute_av_description] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributeAvDescription($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_av_description !== $v) { + $this->attribute_av_description = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION; + } + + + return $this; + } // setAttributeAvDescription() + + /** + * Set the value of [attribute_av_postscriptum] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + */ + public function setAttributeAvPostscriptum($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->attribute_av_postscriptum !== $v) { + $this->attribute_av_postscriptum = $v; + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM; + } + + + return $this; + } // setAttributeAvPostscriptum() + + /** + * 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\OrderProductAttributeCombination 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[] = OrderProductAttributeCombinationTableMap::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\OrderProductAttributeCombination 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[] = OrderProductAttributeCombinationTableMap::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 : OrderProductAttributeCombinationTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + $this->id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('OrderProductId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->order_product_id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributeTitle', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_title = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributeChapo', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_chapo = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributeDescription', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_description = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributePostscriptumn', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_postscriptumn = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributeAvTitle', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_av_title = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributeAvChapo', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_av_chapo = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributeAvDescription', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_av_description = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : OrderProductAttributeCombinationTableMap::translateFieldName('AttributeAvPostscriptum', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_av_postscriptum = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 10 + $startcol : OrderProductAttributeCombinationTableMap::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 ? 11 + $startcol : OrderProductAttributeCombinationTableMap::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 + 12; // 12 = OrderProductAttributeCombinationTableMap::NUM_HYDRATE_COLUMNS. + + } catch (Exception $e) { + throw new PropelException("Error populating \Thelia\Model\OrderProductAttributeCombination 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->aOrderProduct !== null && $this->order_product_id !== $this->aOrderProduct->getId()) { + $this->aOrderProduct = 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(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + } + + // We don't need to alter the object instance pool; we're just modifying this instance + // already in the pool. + + $dataFetcher = ChildOrderProductAttributeCombinationQuery::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->aOrderProduct = null; + } // if (deep) + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param ConnectionInterface $con + * @return void + * @throws PropelException + * @see OrderProductAttributeCombination::setDeleted() + * @see OrderProductAttributeCombination::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(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + try { + $deleteQuery = ChildOrderProductAttributeCombinationQuery::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(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + $isInsert = $this->isNew(); + try { + $ret = $this->preSave($con); + if ($isInsert) { + $ret = $ret && $this->preInsert($con); + // timestampable behavior + if (!$this->isColumnModified(OrderProductAttributeCombinationTableMap::CREATED_AT)) { + $this->setCreatedAt(time()); + } + if (!$this->isColumnModified(OrderProductAttributeCombinationTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } else { + $ret = $ret && $this->preUpdate($con); + // timestampable behavior + if ($this->isModified() && !$this->isColumnModified(OrderProductAttributeCombinationTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } + if ($ret) { + $affectedRows = $this->doSave($con); + if ($isInsert) { + $this->postInsert($con); + } else { + $this->postUpdate($con); + } + $this->postSave($con); + OrderProductAttributeCombinationTableMap::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->aOrderProduct !== null) { + if ($this->aOrderProduct->isModified() || $this->aOrderProduct->isNew()) { + $affectedRows += $this->aOrderProduct->save($con); + } + $this->setOrderProduct($this->aOrderProduct); + } + + 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[] = OrderProductAttributeCombinationTableMap::ID; + if (null !== $this->id) { + throw new PropelException('Cannot insert a value for auto-increment primary key (' . OrderProductAttributeCombinationTableMap::ID . ')'); + } + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ID)) { + $modifiedColumns[':p' . $index++] = 'ID'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID)) { + $modifiedColumns[':p' . $index++] = 'ORDER_PRODUCT_ID'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_TITLE'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_CHAPO'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_DESCRIPTION'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_POSTSCRIPTUMN'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_AV_TITLE'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_AV_CHAPO'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_AV_DESCRIPTION'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_AV_POSTSCRIPTUM'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::CREATED_AT)) { + $modifiedColumns[':p' . $index++] = 'CREATED_AT'; + } + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::UPDATED_AT)) { + $modifiedColumns[':p' . $index++] = 'UPDATED_AT'; + } + + $sql = sprintf( + 'INSERT INTO order_product_attribute_combination (%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 'ORDER_PRODUCT_ID': + $stmt->bindValue($identifier, $this->order_product_id, PDO::PARAM_INT); + break; + case 'ATTRIBUTE_TITLE': + $stmt->bindValue($identifier, $this->attribute_title, PDO::PARAM_STR); + break; + case 'ATTRIBUTE_CHAPO': + $stmt->bindValue($identifier, $this->attribute_chapo, PDO::PARAM_STR); + break; + case 'ATTRIBUTE_DESCRIPTION': + $stmt->bindValue($identifier, $this->attribute_description, PDO::PARAM_STR); + break; + case 'ATTRIBUTE_POSTSCRIPTUMN': + $stmt->bindValue($identifier, $this->attribute_postscriptumn, PDO::PARAM_STR); + break; + case 'ATTRIBUTE_AV_TITLE': + $stmt->bindValue($identifier, $this->attribute_av_title, PDO::PARAM_STR); + break; + case 'ATTRIBUTE_AV_CHAPO': + $stmt->bindValue($identifier, $this->attribute_av_chapo, PDO::PARAM_STR); + break; + case 'ATTRIBUTE_AV_DESCRIPTION': + $stmt->bindValue($identifier, $this->attribute_av_description, PDO::PARAM_STR); + break; + case 'ATTRIBUTE_AV_POSTSCRIPTUM': + $stmt->bindValue($identifier, $this->attribute_av_postscriptum, PDO::PARAM_STR); + break; + case 'CREATED_AT': + $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; + case 'UPDATED_AT': + $stmt->bindValue($identifier, $this->updated_at ? $this->updated_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; + } + } + $stmt->execute(); + } 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 = OrderProductAttributeCombinationTableMap::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->getOrderProductId(); + break; + case 2: + return $this->getAttributeTitle(); + break; + case 3: + return $this->getAttributeChapo(); + break; + case 4: + return $this->getAttributeDescription(); + break; + case 5: + return $this->getAttributePostscriptumn(); + break; + case 6: + return $this->getAttributeAvTitle(); + break; + case 7: + return $this->getAttributeAvChapo(); + break; + case 8: + return $this->getAttributeAvDescription(); + break; + case 9: + return $this->getAttributeAvPostscriptum(); + break; + case 10: + return $this->getCreatedAt(); + break; + case 11: + 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['OrderProductAttributeCombination'][$this->getPrimaryKey()])) { + return '*RECURSION*'; + } + $alreadyDumpedObjects['OrderProductAttributeCombination'][$this->getPrimaryKey()] = true; + $keys = OrderProductAttributeCombinationTableMap::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getId(), + $keys[1] => $this->getOrderProductId(), + $keys[2] => $this->getAttributeTitle(), + $keys[3] => $this->getAttributeChapo(), + $keys[4] => $this->getAttributeDescription(), + $keys[5] => $this->getAttributePostscriptumn(), + $keys[6] => $this->getAttributeAvTitle(), + $keys[7] => $this->getAttributeAvChapo(), + $keys[8] => $this->getAttributeAvDescription(), + $keys[9] => $this->getAttributeAvPostscriptum(), + $keys[10] => $this->getCreatedAt(), + $keys[11] => $this->getUpdatedAt(), + ); + $virtualColumns = $this->virtualColumns; + foreach($virtualColumns as $key => $virtualColumn) + { + $result[$key] = $virtualColumn; + } + + if ($includeForeignObjects) { + if (null !== $this->aOrderProduct) { + $result['OrderProduct'] = $this->aOrderProduct->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 = OrderProductAttributeCombinationTableMap::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->setOrderProductId($value); + break; + case 2: + $this->setAttributeTitle($value); + break; + case 3: + $this->setAttributeChapo($value); + break; + case 4: + $this->setAttributeDescription($value); + break; + case 5: + $this->setAttributePostscriptumn($value); + break; + case 6: + $this->setAttributeAvTitle($value); + break; + case 7: + $this->setAttributeAvChapo($value); + break; + case 8: + $this->setAttributeAvDescription($value); + break; + case 9: + $this->setAttributeAvPostscriptum($value); + break; + case 10: + $this->setCreatedAt($value); + break; + case 11: + $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 = OrderProductAttributeCombinationTableMap::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setOrderProductId($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setAttributeTitle($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setAttributeChapo($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setAttributeDescription($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setAttributePostscriptumn($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setAttributeAvTitle($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setAttributeAvChapo($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setAttributeAvDescription($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setAttributeAvPostscriptum($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setCreatedAt($arr[$keys[10]]); + if (array_key_exists($keys[11], $arr)) $this->setUpdatedAt($arr[$keys[11]]); + } + + /** + * 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(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ID)) $criteria->add(OrderProductAttributeCombinationTableMap::ID, $this->id); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID)) $criteria->add(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID, $this->order_product_id); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE, $this->attribute_title); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO, $this->attribute_chapo); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION, $this->attribute_description); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN, $this->attribute_postscriptumn); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE, $this->attribute_av_title); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO, $this->attribute_av_chapo); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION, $this->attribute_av_description); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM)) $criteria->add(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM, $this->attribute_av_postscriptum); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::CREATED_AT)) $criteria->add(OrderProductAttributeCombinationTableMap::CREATED_AT, $this->created_at); + if ($this->isColumnModified(OrderProductAttributeCombinationTableMap::UPDATED_AT)) $criteria->add(OrderProductAttributeCombinationTableMap::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(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + $criteria->add(OrderProductAttributeCombinationTableMap::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\OrderProductAttributeCombination (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->setOrderProductId($this->getOrderProductId()); + $copyObj->setAttributeTitle($this->getAttributeTitle()); + $copyObj->setAttributeChapo($this->getAttributeChapo()); + $copyObj->setAttributeDescription($this->getAttributeDescription()); + $copyObj->setAttributePostscriptumn($this->getAttributePostscriptumn()); + $copyObj->setAttributeAvTitle($this->getAttributeAvTitle()); + $copyObj->setAttributeAvChapo($this->getAttributeAvChapo()); + $copyObj->setAttributeAvDescription($this->getAttributeAvDescription()); + $copyObj->setAttributeAvPostscriptum($this->getAttributeAvPostscriptum()); + $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\OrderProductAttributeCombination 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 ChildOrderProduct object. + * + * @param ChildOrderProduct $v + * @return \Thelia\Model\OrderProductAttributeCombination The current object (for fluent API support) + * @throws PropelException + */ + public function setOrderProduct(ChildOrderProduct $v = null) + { + if ($v === null) { + $this->setOrderProductId(NULL); + } else { + $this->setOrderProductId($v->getId()); + } + + $this->aOrderProduct = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildOrderProduct object, it will not be re-added. + if ($v !== null) { + $v->addOrderProductAttributeCombination($this); + } + + + return $this; + } + + + /** + * Get the associated ChildOrderProduct object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildOrderProduct The associated ChildOrderProduct object. + * @throws PropelException + */ + public function getOrderProduct(ConnectionInterface $con = null) + { + if ($this->aOrderProduct === null && ($this->order_product_id !== null)) { + $this->aOrderProduct = ChildOrderProductQuery::create()->findPk($this->order_product_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->aOrderProduct->addOrderProductAttributeCombinations($this); + */ + } + + return $this->aOrderProduct; + } + + /** + * Clears the current object and sets all attributes to their default values + */ + public function clear() + { + $this->id = null; + $this->order_product_id = null; + $this->attribute_title = null; + $this->attribute_chapo = null; + $this->attribute_description = null; + $this->attribute_postscriptumn = null; + $this->attribute_av_title = null; + $this->attribute_av_chapo = null; + $this->attribute_av_description = null; + $this->attribute_av_postscriptum = 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->aOrderProduct = null; + } + + /** + * Return the string representation of this object + * + * @return string + */ + public function __toString() + { + return (string) $this->exportTo(OrderProductAttributeCombinationTableMap::DEFAULT_STRING_FORMAT); + } + + // timestampable behavior + + /** + * Mark the current object so that the update date doesn't get updated during next save + * + * @return ChildOrderProductAttributeCombination The current object (for fluent API support) + */ + public function keepUpdateDateUnchanged() + { + $this->modifiedColumns[] = OrderProductAttributeCombinationTableMap::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/OrderProductAttributeCombinationQuery.php b/core/lib/Thelia/Model/Base/OrderProductAttributeCombinationQuery.php new file mode 100644 index 000000000..9e8298aa5 --- /dev/null +++ b/core/lib/Thelia/Model/Base/OrderProductAttributeCombinationQuery.php @@ -0,0 +1,897 @@ +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 ChildOrderProductAttributeCombination|array|mixed the result, formatted by the current formatter + */ + public function findPk($key, $con = null) + { + if ($key === null) { + return null; + } + if ((null !== ($obj = OrderProductAttributeCombinationTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { + // the object is already in the instance pool + return $obj; + } + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(OrderProductAttributeCombinationTableMap::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 ChildOrderProductAttributeCombination A model object, or null if the key is not found + */ + protected function findPkSimple($key, $con) + { + $sql = 'SELECT ID, ORDER_PRODUCT_ID, ATTRIBUTE_TITLE, ATTRIBUTE_CHAPO, ATTRIBUTE_DESCRIPTION, ATTRIBUTE_POSTSCRIPTUMN, ATTRIBUTE_AV_TITLE, ATTRIBUTE_AV_CHAPO, ATTRIBUTE_AV_DESCRIPTION, ATTRIBUTE_AV_POSTSCRIPTUM, CREATED_AT, UPDATED_AT FROM order_product_attribute_combination 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 ChildOrderProductAttributeCombination(); + $obj->hydrate($row); + OrderProductAttributeCombinationTableMap::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 ChildOrderProductAttributeCombination|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 ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByPrimaryKey($key) + { + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::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 ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByPrimaryKeys($keys) + { + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::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 ChildOrderProductAttributeCombinationQuery 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(OrderProductAttributeCombinationTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($id['max'])) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ID, $id['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ID, $id, $comparison); + } + + /** + * Filter the query on the order_product_id column + * + * Example usage: + * + * $query->filterByOrderProductId(1234); // WHERE order_product_id = 1234 + * $query->filterByOrderProductId(array(12, 34)); // WHERE order_product_id IN (12, 34) + * $query->filterByOrderProductId(array('min' => 12)); // WHERE order_product_id > 12 + * + * + * @see filterByOrderProduct() + * + * @param mixed $orderProductId 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 ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByOrderProductId($orderProductId = null, $comparison = null) + { + if (is_array($orderProductId)) { + $useMinMax = false; + if (isset($orderProductId['min'])) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID, $orderProductId['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($orderProductId['max'])) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID, $orderProductId['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID, $orderProductId, $comparison); + } + + /** + * Filter the query on the attribute_title column + * + * Example usage: + * + * $query->filterByAttributeTitle('fooValue'); // WHERE attribute_title = 'fooValue' + * $query->filterByAttributeTitle('%fooValue%'); // WHERE attribute_title LIKE '%fooValue%' + * + * + * @param string $attributeTitle 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 ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributeTitle($attributeTitle = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeTitle)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeTitle)) { + $attributeTitle = str_replace('*', '%', $attributeTitle); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE, $attributeTitle, $comparison); + } + + /** + * Filter the query on the attribute_chapo column + * + * Example usage: + * + * $query->filterByAttributeChapo('fooValue'); // WHERE attribute_chapo = 'fooValue' + * $query->filterByAttributeChapo('%fooValue%'); // WHERE attribute_chapo LIKE '%fooValue%' + * + * + * @param string $attributeChapo 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 ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributeChapo($attributeChapo = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeChapo)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeChapo)) { + $attributeChapo = str_replace('*', '%', $attributeChapo); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO, $attributeChapo, $comparison); + } + + /** + * Filter the query on the attribute_description column + * + * Example usage: + * + * $query->filterByAttributeDescription('fooValue'); // WHERE attribute_description = 'fooValue' + * $query->filterByAttributeDescription('%fooValue%'); // WHERE attribute_description LIKE '%fooValue%' + * + * + * @param string $attributeDescription 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 ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributeDescription($attributeDescription = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeDescription)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeDescription)) { + $attributeDescription = str_replace('*', '%', $attributeDescription); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION, $attributeDescription, $comparison); + } + + /** + * Filter the query on the attribute_postscriptumn column + * + * Example usage: + * + * $query->filterByAttributePostscriptumn('fooValue'); // WHERE attribute_postscriptumn = 'fooValue' + * $query->filterByAttributePostscriptumn('%fooValue%'); // WHERE attribute_postscriptumn LIKE '%fooValue%' + * + * + * @param string $attributePostscriptumn 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 ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributePostscriptumn($attributePostscriptumn = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributePostscriptumn)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributePostscriptumn)) { + $attributePostscriptumn = str_replace('*', '%', $attributePostscriptumn); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN, $attributePostscriptumn, $comparison); + } + + /** + * Filter the query on the attribute_av_title column + * + * Example usage: + * + * $query->filterByAttributeAvTitle('fooValue'); // WHERE attribute_av_title = 'fooValue' + * $query->filterByAttributeAvTitle('%fooValue%'); // WHERE attribute_av_title LIKE '%fooValue%' + * + * + * @param string $attributeAvTitle 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 ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributeAvTitle($attributeAvTitle = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeAvTitle)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeAvTitle)) { + $attributeAvTitle = str_replace('*', '%', $attributeAvTitle); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE, $attributeAvTitle, $comparison); + } + + /** + * Filter the query on the attribute_av_chapo column + * + * Example usage: + * + * $query->filterByAttributeAvChapo('fooValue'); // WHERE attribute_av_chapo = 'fooValue' + * $query->filterByAttributeAvChapo('%fooValue%'); // WHERE attribute_av_chapo LIKE '%fooValue%' + * + * + * @param string $attributeAvChapo 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 ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributeAvChapo($attributeAvChapo = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeAvChapo)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeAvChapo)) { + $attributeAvChapo = str_replace('*', '%', $attributeAvChapo); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO, $attributeAvChapo, $comparison); + } + + /** + * Filter the query on the attribute_av_description column + * + * Example usage: + * + * $query->filterByAttributeAvDescription('fooValue'); // WHERE attribute_av_description = 'fooValue' + * $query->filterByAttributeAvDescription('%fooValue%'); // WHERE attribute_av_description LIKE '%fooValue%' + * + * + * @param string $attributeAvDescription 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 ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributeAvDescription($attributeAvDescription = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeAvDescription)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeAvDescription)) { + $attributeAvDescription = str_replace('*', '%', $attributeAvDescription); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION, $attributeAvDescription, $comparison); + } + + /** + * Filter the query on the attribute_av_postscriptum column + * + * Example usage: + * + * $query->filterByAttributeAvPostscriptum('fooValue'); // WHERE attribute_av_postscriptum = 'fooValue' + * $query->filterByAttributeAvPostscriptum('%fooValue%'); // WHERE attribute_av_postscriptum LIKE '%fooValue%' + * + * + * @param string $attributeAvPostscriptum 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 ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByAttributeAvPostscriptum($attributeAvPostscriptum = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($attributeAvPostscriptum)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $attributeAvPostscriptum)) { + $attributeAvPostscriptum = str_replace('*', '%', $attributeAvPostscriptum); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM, $attributeAvPostscriptum, $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 ChildOrderProductAttributeCombinationQuery 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(OrderProductAttributeCombinationTableMap::CREATED_AT, $createdAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($createdAt['max'])) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::CREATED_AT, $createdAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::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 ChildOrderProductAttributeCombinationQuery 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(OrderProductAttributeCombinationTableMap::UPDATED_AT, $updatedAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($updatedAt['max'])) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::UPDATED_AT, $updatedAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::UPDATED_AT, $updatedAt, $comparison); + } + + /** + * Filter the query by a related \Thelia\Model\OrderProduct object + * + * @param \Thelia\Model\OrderProduct|ObjectCollection $orderProduct The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function filterByOrderProduct($orderProduct, $comparison = null) + { + if ($orderProduct instanceof \Thelia\Model\OrderProduct) { + return $this + ->addUsingAlias(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID, $orderProduct->getId(), $comparison); + } elseif ($orderProduct instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID, $orderProduct->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByOrderProduct() only accepts arguments of type \Thelia\Model\OrderProduct or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the OrderProduct relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function joinOrderProduct($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('OrderProduct'); + + // 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, 'OrderProduct'); + } + + return $this; + } + + /** + * Use the OrderProduct relation OrderProduct 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\OrderProductQuery A secondary query class using the current class as primary query + */ + public function useOrderProductQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinOrderProduct($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'OrderProduct', '\Thelia\Model\OrderProductQuery'); + } + + /** + * Exclude object from result + * + * @param ChildOrderProductAttributeCombination $orderProductAttributeCombination Object to remove from the list of results + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function prune($orderProductAttributeCombination = null) + { + if ($orderProductAttributeCombination) { + $this->addUsingAlias(OrderProductAttributeCombinationTableMap::ID, $orderProductAttributeCombination->getId(), Criteria::NOT_EQUAL); + } + + return $this; + } + + /** + * Deletes all rows from the order_product_attribute_combination 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(OrderProductAttributeCombinationTableMap::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). + OrderProductAttributeCombinationTableMap::clearInstancePool(); + OrderProductAttributeCombinationTableMap::clearRelatedInstancePool(); + + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $affectedRows; + } + + /** + * Performs a DELETE on the database, given a ChildOrderProductAttributeCombination or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ChildOrderProductAttributeCombination 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(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + } + + $criteria = $this; + + // Set the correct dbName + $criteria->setDbName(OrderProductAttributeCombinationTableMap::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(); + + + OrderProductAttributeCombinationTableMap::removeInstanceFromPool($criteria); + + $affectedRows += ModelCriteria::delete($con); + OrderProductAttributeCombinationTableMap::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 ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function recentlyUpdated($nbDays = 7) + { + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::UPDATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Filter by the latest created + * + * @param int $nbDays Maximum age of in days + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function recentlyCreated($nbDays = 7) + { + return $this->addUsingAlias(OrderProductAttributeCombinationTableMap::CREATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Order by update date desc + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function lastUpdatedFirst() + { + return $this->addDescendingOrderByColumn(OrderProductAttributeCombinationTableMap::UPDATED_AT); + } + + /** + * Order by update date asc + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function firstUpdatedFirst() + { + return $this->addAscendingOrderByColumn(OrderProductAttributeCombinationTableMap::UPDATED_AT); + } + + /** + * Order by create date desc + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function lastCreatedFirst() + { + return $this->addDescendingOrderByColumn(OrderProductAttributeCombinationTableMap::CREATED_AT); + } + + /** + * Order by create date asc + * + * @return ChildOrderProductAttributeCombinationQuery The current query, for fluid interface + */ + public function firstCreatedFirst() + { + return $this->addAscendingOrderByColumn(OrderProductAttributeCombinationTableMap::CREATED_AT); + } + +} // OrderProductAttributeCombinationQuery diff --git a/core/lib/Thelia/Model/Base/OrderProductTax.php b/core/lib/Thelia/Model/Base/OrderProductTax.php new file mode 100644 index 000000000..544755ff4 --- /dev/null +++ b/core/lib/Thelia/Model/Base/OrderProductTax.php @@ -0,0 +1,1534 @@ +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 OrderProductTax instance. If + * obj is an instance of OrderProductTax, delegates to + * equals(OrderProductTax). 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 OrderProductTax 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 OrderProductTax 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 [order_product_id] column value. + * + * @return int + */ + public function getOrderProductId() + { + + return $this->order_product_id; + } + + /** + * Get the [title] column value. + * + * @return string + */ + public function getTitle() + { + + return $this->title; + } + + /** + * Get the [description] column value. + * + * @return string + */ + public function getDescription() + { + + return $this->description; + } + + /** + * Get the [amount] column value. + * + * @return double + */ + public function getAmount() + { + + return $this->amount; + } + + /** + * 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\OrderProductTax 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[] = OrderProductTaxTableMap::ID; + } + + + return $this; + } // setId() + + /** + * Set the value of [order_product_id] column. + * + * @param int $v new value + * @return \Thelia\Model\OrderProductTax The current object (for fluent API support) + */ + public function setOrderProductId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->order_product_id !== $v) { + $this->order_product_id = $v; + $this->modifiedColumns[] = OrderProductTaxTableMap::ORDER_PRODUCT_ID; + } + + if ($this->aOrderProduct !== null && $this->aOrderProduct->getId() !== $v) { + $this->aOrderProduct = null; + } + + + return $this; + } // setOrderProductId() + + /** + * Set the value of [title] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductTax The current object (for fluent API support) + */ + public function setTitle($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->title !== $v) { + $this->title = $v; + $this->modifiedColumns[] = OrderProductTaxTableMap::TITLE; + } + + + return $this; + } // setTitle() + + /** + * Set the value of [description] column. + * + * @param string $v new value + * @return \Thelia\Model\OrderProductTax The current object (for fluent API support) + */ + public function setDescription($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->description !== $v) { + $this->description = $v; + $this->modifiedColumns[] = OrderProductTaxTableMap::DESCRIPTION; + } + + + return $this; + } // setDescription() + + /** + * Set the value of [amount] column. + * + * @param double $v new value + * @return \Thelia\Model\OrderProductTax The current object (for fluent API support) + */ + public function setAmount($v) + { + if ($v !== null) { + $v = (double) $v; + } + + if ($this->amount !== $v) { + $this->amount = $v; + $this->modifiedColumns[] = OrderProductTaxTableMap::AMOUNT; + } + + + return $this; + } // setAmount() + + /** + * 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\OrderProductTax 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[] = OrderProductTaxTableMap::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\OrderProductTax 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[] = OrderProductTaxTableMap::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 : OrderProductTaxTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + $this->id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : OrderProductTaxTableMap::translateFieldName('OrderProductId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->order_product_id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : OrderProductTaxTableMap::translateFieldName('Title', TableMap::TYPE_PHPNAME, $indexType)]; + $this->title = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : OrderProductTaxTableMap::translateFieldName('Description', TableMap::TYPE_PHPNAME, $indexType)]; + $this->description = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : OrderProductTaxTableMap::translateFieldName('Amount', TableMap::TYPE_PHPNAME, $indexType)]; + $this->amount = (null !== $col) ? (double) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : OrderProductTaxTableMap::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 : OrderProductTaxTableMap::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 + 7; // 7 = OrderProductTaxTableMap::NUM_HYDRATE_COLUMNS. + + } catch (Exception $e) { + throw new PropelException("Error populating \Thelia\Model\OrderProductTax 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->aOrderProduct !== null && $this->order_product_id !== $this->aOrderProduct->getId()) { + $this->aOrderProduct = 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(OrderProductTaxTableMap::DATABASE_NAME); + } + + // We don't need to alter the object instance pool; we're just modifying this instance + // already in the pool. + + $dataFetcher = ChildOrderProductTaxQuery::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->aOrderProduct = null; + } // if (deep) + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param ConnectionInterface $con + * @return void + * @throws PropelException + * @see OrderProductTax::setDeleted() + * @see OrderProductTax::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(OrderProductTaxTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + try { + $deleteQuery = ChildOrderProductTaxQuery::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(OrderProductTaxTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + $isInsert = $this->isNew(); + try { + $ret = $this->preSave($con); + if ($isInsert) { + $ret = $ret && $this->preInsert($con); + // timestampable behavior + if (!$this->isColumnModified(OrderProductTaxTableMap::CREATED_AT)) { + $this->setCreatedAt(time()); + } + if (!$this->isColumnModified(OrderProductTaxTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } else { + $ret = $ret && $this->preUpdate($con); + // timestampable behavior + if ($this->isModified() && !$this->isColumnModified(OrderProductTaxTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } + if ($ret) { + $affectedRows = $this->doSave($con); + if ($isInsert) { + $this->postInsert($con); + } else { + $this->postUpdate($con); + } + $this->postSave($con); + OrderProductTaxTableMap::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->aOrderProduct !== null) { + if ($this->aOrderProduct->isModified() || $this->aOrderProduct->isNew()) { + $affectedRows += $this->aOrderProduct->save($con); + } + $this->setOrderProduct($this->aOrderProduct); + } + + 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[] = OrderProductTaxTableMap::ID; + if (null !== $this->id) { + throw new PropelException('Cannot insert a value for auto-increment primary key (' . OrderProductTaxTableMap::ID . ')'); + } + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(OrderProductTaxTableMap::ID)) { + $modifiedColumns[':p' . $index++] = 'ID'; + } + if ($this->isColumnModified(OrderProductTaxTableMap::ORDER_PRODUCT_ID)) { + $modifiedColumns[':p' . $index++] = 'ORDER_PRODUCT_ID'; + } + if ($this->isColumnModified(OrderProductTaxTableMap::TITLE)) { + $modifiedColumns[':p' . $index++] = 'TITLE'; + } + if ($this->isColumnModified(OrderProductTaxTableMap::DESCRIPTION)) { + $modifiedColumns[':p' . $index++] = 'DESCRIPTION'; + } + if ($this->isColumnModified(OrderProductTaxTableMap::AMOUNT)) { + $modifiedColumns[':p' . $index++] = 'AMOUNT'; + } + if ($this->isColumnModified(OrderProductTaxTableMap::CREATED_AT)) { + $modifiedColumns[':p' . $index++] = 'CREATED_AT'; + } + if ($this->isColumnModified(OrderProductTaxTableMap::UPDATED_AT)) { + $modifiedColumns[':p' . $index++] = 'UPDATED_AT'; + } + + $sql = sprintf( + 'INSERT INTO order_product_tax (%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 'ORDER_PRODUCT_ID': + $stmt->bindValue($identifier, $this->order_product_id, PDO::PARAM_INT); + break; + case 'TITLE': + $stmt->bindValue($identifier, $this->title, PDO::PARAM_STR); + break; + case 'DESCRIPTION': + $stmt->bindValue($identifier, $this->description, PDO::PARAM_STR); + break; + case 'AMOUNT': + $stmt->bindValue($identifier, $this->amount, PDO::PARAM_STR); + break; + case 'CREATED_AT': + $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; + case 'UPDATED_AT': + $stmt->bindValue($identifier, $this->updated_at ? $this->updated_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; + } + } + $stmt->execute(); + } 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 = OrderProductTaxTableMap::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->getOrderProductId(); + break; + case 2: + return $this->getTitle(); + break; + case 3: + return $this->getDescription(); + break; + case 4: + return $this->getAmount(); + break; + case 5: + return $this->getCreatedAt(); + break; + case 6: + 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['OrderProductTax'][$this->getPrimaryKey()])) { + return '*RECURSION*'; + } + $alreadyDumpedObjects['OrderProductTax'][$this->getPrimaryKey()] = true; + $keys = OrderProductTaxTableMap::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getId(), + $keys[1] => $this->getOrderProductId(), + $keys[2] => $this->getTitle(), + $keys[3] => $this->getDescription(), + $keys[4] => $this->getAmount(), + $keys[5] => $this->getCreatedAt(), + $keys[6] => $this->getUpdatedAt(), + ); + $virtualColumns = $this->virtualColumns; + foreach($virtualColumns as $key => $virtualColumn) + { + $result[$key] = $virtualColumn; + } + + if ($includeForeignObjects) { + if (null !== $this->aOrderProduct) { + $result['OrderProduct'] = $this->aOrderProduct->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 = OrderProductTaxTableMap::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->setOrderProductId($value); + break; + case 2: + $this->setTitle($value); + break; + case 3: + $this->setDescription($value); + break; + case 4: + $this->setAmount($value); + break; + case 5: + $this->setCreatedAt($value); + break; + case 6: + $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 = OrderProductTaxTableMap::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setOrderProductId($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTitle($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setDescription($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setAmount($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]]); + } + + /** + * 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(OrderProductTaxTableMap::DATABASE_NAME); + + if ($this->isColumnModified(OrderProductTaxTableMap::ID)) $criteria->add(OrderProductTaxTableMap::ID, $this->id); + if ($this->isColumnModified(OrderProductTaxTableMap::ORDER_PRODUCT_ID)) $criteria->add(OrderProductTaxTableMap::ORDER_PRODUCT_ID, $this->order_product_id); + if ($this->isColumnModified(OrderProductTaxTableMap::TITLE)) $criteria->add(OrderProductTaxTableMap::TITLE, $this->title); + if ($this->isColumnModified(OrderProductTaxTableMap::DESCRIPTION)) $criteria->add(OrderProductTaxTableMap::DESCRIPTION, $this->description); + if ($this->isColumnModified(OrderProductTaxTableMap::AMOUNT)) $criteria->add(OrderProductTaxTableMap::AMOUNT, $this->amount); + if ($this->isColumnModified(OrderProductTaxTableMap::CREATED_AT)) $criteria->add(OrderProductTaxTableMap::CREATED_AT, $this->created_at); + if ($this->isColumnModified(OrderProductTaxTableMap::UPDATED_AT)) $criteria->add(OrderProductTaxTableMap::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(OrderProductTaxTableMap::DATABASE_NAME); + $criteria->add(OrderProductTaxTableMap::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\OrderProductTax (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->setOrderProductId($this->getOrderProductId()); + $copyObj->setTitle($this->getTitle()); + $copyObj->setDescription($this->getDescription()); + $copyObj->setAmount($this->getAmount()); + $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\OrderProductTax 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 ChildOrderProduct object. + * + * @param ChildOrderProduct $v + * @return \Thelia\Model\OrderProductTax The current object (for fluent API support) + * @throws PropelException + */ + public function setOrderProduct(ChildOrderProduct $v = null) + { + if ($v === null) { + $this->setOrderProductId(NULL); + } else { + $this->setOrderProductId($v->getId()); + } + + $this->aOrderProduct = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildOrderProduct object, it will not be re-added. + if ($v !== null) { + $v->addOrderProductTax($this); + } + + + return $this; + } + + + /** + * Get the associated ChildOrderProduct object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildOrderProduct The associated ChildOrderProduct object. + * @throws PropelException + */ + public function getOrderProduct(ConnectionInterface $con = null) + { + if ($this->aOrderProduct === null && ($this->order_product_id !== null)) { + $this->aOrderProduct = ChildOrderProductQuery::create()->findPk($this->order_product_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->aOrderProduct->addOrderProductTaxes($this); + */ + } + + return $this->aOrderProduct; + } + + /** + * Clears the current object and sets all attributes to their default values + */ + public function clear() + { + $this->id = null; + $this->order_product_id = null; + $this->title = null; + $this->description = null; + $this->amount = 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->aOrderProduct = null; + } + + /** + * Return the string representation of this object + * + * @return string + */ + public function __toString() + { + return (string) $this->exportTo(OrderProductTaxTableMap::DEFAULT_STRING_FORMAT); + } + + // timestampable behavior + + /** + * Mark the current object so that the update date doesn't get updated during next save + * + * @return ChildOrderProductTax The current object (for fluent API support) + */ + public function keepUpdateDateUnchanged() + { + $this->modifiedColumns[] = OrderProductTaxTableMap::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/OrderProductTaxQuery.php b/core/lib/Thelia/Model/Base/OrderProductTaxQuery.php new file mode 100644 index 000000000..d37c2c501 --- /dev/null +++ b/core/lib/Thelia/Model/Base/OrderProductTaxQuery.php @@ -0,0 +1,744 @@ +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 ChildOrderProductTax|array|mixed the result, formatted by the current formatter + */ + public function findPk($key, $con = null) + { + if ($key === null) { + return null; + } + if ((null !== ($obj = OrderProductTaxTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { + // the object is already in the instance pool + return $obj; + } + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(OrderProductTaxTableMap::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 ChildOrderProductTax A model object, or null if the key is not found + */ + protected function findPkSimple($key, $con) + { + $sql = 'SELECT ID, ORDER_PRODUCT_ID, TITLE, DESCRIPTION, AMOUNT, CREATED_AT, UPDATED_AT FROM order_product_tax 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 ChildOrderProductTax(); + $obj->hydrate($row); + OrderProductTaxTableMap::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 ChildOrderProductTax|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 ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function filterByPrimaryKey($key) + { + + return $this->addUsingAlias(OrderProductTaxTableMap::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 ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function filterByPrimaryKeys($keys) + { + + return $this->addUsingAlias(OrderProductTaxTableMap::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 ChildOrderProductTaxQuery 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(OrderProductTaxTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($id['max'])) { + $this->addUsingAlias(OrderProductTaxTableMap::ID, $id['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductTaxTableMap::ID, $id, $comparison); + } + + /** + * Filter the query on the order_product_id column + * + * Example usage: + * + * $query->filterByOrderProductId(1234); // WHERE order_product_id = 1234 + * $query->filterByOrderProductId(array(12, 34)); // WHERE order_product_id IN (12, 34) + * $query->filterByOrderProductId(array('min' => 12)); // WHERE order_product_id > 12 + * + * + * @see filterByOrderProduct() + * + * @param mixed $orderProductId 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 ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function filterByOrderProductId($orderProductId = null, $comparison = null) + { + if (is_array($orderProductId)) { + $useMinMax = false; + if (isset($orderProductId['min'])) { + $this->addUsingAlias(OrderProductTaxTableMap::ORDER_PRODUCT_ID, $orderProductId['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($orderProductId['max'])) { + $this->addUsingAlias(OrderProductTaxTableMap::ORDER_PRODUCT_ID, $orderProductId['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductTaxTableMap::ORDER_PRODUCT_ID, $orderProductId, $comparison); + } + + /** + * Filter the query on the title column + * + * Example usage: + * + * $query->filterByTitle('fooValue'); // WHERE title = 'fooValue' + * $query->filterByTitle('%fooValue%'); // WHERE title LIKE '%fooValue%' + * + * + * @param string $title 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 ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function filterByTitle($title = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($title)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $title)) { + $title = str_replace('*', '%', $title); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTaxTableMap::TITLE, $title, $comparison); + } + + /** + * Filter the query on the description column + * + * Example usage: + * + * $query->filterByDescription('fooValue'); // WHERE description = 'fooValue' + * $query->filterByDescription('%fooValue%'); // WHERE description LIKE '%fooValue%' + * + * + * @param string $description 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 ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function filterByDescription($description = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($description)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $description)) { + $description = str_replace('*', '%', $description); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(OrderProductTaxTableMap::DESCRIPTION, $description, $comparison); + } + + /** + * Filter the query on the amount column + * + * Example usage: + * + * $query->filterByAmount(1234); // WHERE amount = 1234 + * $query->filterByAmount(array(12, 34)); // WHERE amount IN (12, 34) + * $query->filterByAmount(array('min' => 12)); // WHERE amount > 12 + * + * + * @param mixed $amount 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 ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function filterByAmount($amount = null, $comparison = null) + { + if (is_array($amount)) { + $useMinMax = false; + if (isset($amount['min'])) { + $this->addUsingAlias(OrderProductTaxTableMap::AMOUNT, $amount['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($amount['max'])) { + $this->addUsingAlias(OrderProductTaxTableMap::AMOUNT, $amount['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductTaxTableMap::AMOUNT, $amount, $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 ChildOrderProductTaxQuery 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(OrderProductTaxTableMap::CREATED_AT, $createdAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($createdAt['max'])) { + $this->addUsingAlias(OrderProductTaxTableMap::CREATED_AT, $createdAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductTaxTableMap::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 ChildOrderProductTaxQuery 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(OrderProductTaxTableMap::UPDATED_AT, $updatedAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($updatedAt['max'])) { + $this->addUsingAlias(OrderProductTaxTableMap::UPDATED_AT, $updatedAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(OrderProductTaxTableMap::UPDATED_AT, $updatedAt, $comparison); + } + + /** + * Filter the query by a related \Thelia\Model\OrderProduct object + * + * @param \Thelia\Model\OrderProduct|ObjectCollection $orderProduct The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function filterByOrderProduct($orderProduct, $comparison = null) + { + if ($orderProduct instanceof \Thelia\Model\OrderProduct) { + return $this + ->addUsingAlias(OrderProductTaxTableMap::ORDER_PRODUCT_ID, $orderProduct->getId(), $comparison); + } elseif ($orderProduct instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(OrderProductTaxTableMap::ORDER_PRODUCT_ID, $orderProduct->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByOrderProduct() only accepts arguments of type \Thelia\Model\OrderProduct or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the OrderProduct relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function joinOrderProduct($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('OrderProduct'); + + // 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, 'OrderProduct'); + } + + return $this; + } + + /** + * Use the OrderProduct relation OrderProduct 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\OrderProductQuery A secondary query class using the current class as primary query + */ + public function useOrderProductQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinOrderProduct($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'OrderProduct', '\Thelia\Model\OrderProductQuery'); + } + + /** + * Exclude object from result + * + * @param ChildOrderProductTax $orderProductTax Object to remove from the list of results + * + * @return ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function prune($orderProductTax = null) + { + if ($orderProductTax) { + $this->addUsingAlias(OrderProductTaxTableMap::ID, $orderProductTax->getId(), Criteria::NOT_EQUAL); + } + + return $this; + } + + /** + * Deletes all rows from the order_product_tax 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(OrderProductTaxTableMap::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). + OrderProductTaxTableMap::clearInstancePool(); + OrderProductTaxTableMap::clearRelatedInstancePool(); + + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $affectedRows; + } + + /** + * Performs a DELETE on the database, given a ChildOrderProductTax or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ChildOrderProductTax 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(OrderProductTaxTableMap::DATABASE_NAME); + } + + $criteria = $this; + + // Set the correct dbName + $criteria->setDbName(OrderProductTaxTableMap::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(); + + + OrderProductTaxTableMap::removeInstanceFromPool($criteria); + + $affectedRows += ModelCriteria::delete($con); + OrderProductTaxTableMap::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 ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function recentlyUpdated($nbDays = 7) + { + return $this->addUsingAlias(OrderProductTaxTableMap::UPDATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Filter by the latest created + * + * @param int $nbDays Maximum age of in days + * + * @return ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function recentlyCreated($nbDays = 7) + { + return $this->addUsingAlias(OrderProductTaxTableMap::CREATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Order by update date desc + * + * @return ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function lastUpdatedFirst() + { + return $this->addDescendingOrderByColumn(OrderProductTaxTableMap::UPDATED_AT); + } + + /** + * Order by update date asc + * + * @return ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function firstUpdatedFirst() + { + return $this->addAscendingOrderByColumn(OrderProductTaxTableMap::UPDATED_AT); + } + + /** + * Order by create date desc + * + * @return ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function lastCreatedFirst() + { + return $this->addDescendingOrderByColumn(OrderProductTaxTableMap::CREATED_AT); + } + + /** + * Order by create date asc + * + * @return ChildOrderProductTaxQuery The current query, for fluid interface + */ + public function firstCreatedFirst() + { + return $this->addAscendingOrderByColumn(OrderProductTaxTableMap::CREATED_AT); + } + +} // OrderProductTaxQuery diff --git a/core/lib/Thelia/Model/Map/OrderProductAttributeCombinationTableMap.php b/core/lib/Thelia/Model/Map/OrderProductAttributeCombinationTableMap.php new file mode 100644 index 000000000..582bd2305 --- /dev/null +++ b/core/lib/Thelia/Model/Map/OrderProductAttributeCombinationTableMap.php @@ -0,0 +1,503 @@ + array('Id', 'OrderProductId', 'AttributeTitle', 'AttributeChapo', 'AttributeDescription', 'AttributePostscriptumn', 'AttributeAvTitle', 'AttributeAvChapo', 'AttributeAvDescription', 'AttributeAvPostscriptum', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'orderProductId', 'attributeTitle', 'attributeChapo', 'attributeDescription', 'attributePostscriptumn', 'attributeAvTitle', 'attributeAvChapo', 'attributeAvDescription', 'attributeAvPostscriptum', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(OrderProductAttributeCombinationTableMap::ID, OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID, OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE, OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO, OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION, OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM, OrderProductAttributeCombinationTableMap::CREATED_AT, OrderProductAttributeCombinationTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'ORDER_PRODUCT_ID', 'ATTRIBUTE_TITLE', 'ATTRIBUTE_CHAPO', 'ATTRIBUTE_DESCRIPTION', 'ATTRIBUTE_POSTSCRIPTUMN', 'ATTRIBUTE_AV_TITLE', 'ATTRIBUTE_AV_CHAPO', 'ATTRIBUTE_AV_DESCRIPTION', 'ATTRIBUTE_AV_POSTSCRIPTUM', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'order_product_id', 'attribute_title', 'attribute_chapo', 'attribute_description', 'attribute_postscriptumn', 'attribute_av_title', 'attribute_av_chapo', 'attribute_av_description', 'attribute_av_postscriptum', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) + ); + + /** + * 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, 'OrderProductId' => 1, 'AttributeTitle' => 2, 'AttributeChapo' => 3, 'AttributeDescription' => 4, 'AttributePostscriptumn' => 5, 'AttributeAvTitle' => 6, 'AttributeAvChapo' => 7, 'AttributeAvDescription' => 8, 'AttributeAvPostscriptum' => 9, 'CreatedAt' => 10, 'UpdatedAt' => 11, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'orderProductId' => 1, 'attributeTitle' => 2, 'attributeChapo' => 3, 'attributeDescription' => 4, 'attributePostscriptumn' => 5, 'attributeAvTitle' => 6, 'attributeAvChapo' => 7, 'attributeAvDescription' => 8, 'attributeAvPostscriptum' => 9, 'createdAt' => 10, 'updatedAt' => 11, ), + self::TYPE_COLNAME => array(OrderProductAttributeCombinationTableMap::ID => 0, OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID => 1, OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE => 2, OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO => 3, OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION => 4, OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN => 5, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE => 6, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO => 7, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION => 8, OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM => 9, OrderProductAttributeCombinationTableMap::CREATED_AT => 10, OrderProductAttributeCombinationTableMap::UPDATED_AT => 11, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'ORDER_PRODUCT_ID' => 1, 'ATTRIBUTE_TITLE' => 2, 'ATTRIBUTE_CHAPO' => 3, 'ATTRIBUTE_DESCRIPTION' => 4, 'ATTRIBUTE_POSTSCRIPTUMN' => 5, 'ATTRIBUTE_AV_TITLE' => 6, 'ATTRIBUTE_AV_CHAPO' => 7, 'ATTRIBUTE_AV_DESCRIPTION' => 8, 'ATTRIBUTE_AV_POSTSCRIPTUM' => 9, 'CREATED_AT' => 10, 'UPDATED_AT' => 11, ), + self::TYPE_FIELDNAME => array('id' => 0, 'order_product_id' => 1, 'attribute_title' => 2, 'attribute_chapo' => 3, 'attribute_description' => 4, 'attribute_postscriptumn' => 5, 'attribute_av_title' => 6, 'attribute_av_chapo' => 7, 'attribute_av_description' => 8, 'attribute_av_postscriptum' => 9, 'created_at' => 10, 'updated_at' => 11, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ) + ); + + /** + * 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('order_product_attribute_combination'); + $this->setPhpName('OrderProductAttributeCombination'); + $this->setClassName('\\Thelia\\Model\\OrderProductAttributeCombination'); + $this->setPackage('Thelia.Model'); + $this->setUseIdGenerator(true); + // columns + $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); + $this->addForeignKey('ORDER_PRODUCT_ID', 'OrderProductId', 'INTEGER', 'order_product', 'ID', true, null, null); + $this->addColumn('ATTRIBUTE_TITLE', 'AttributeTitle', 'VARCHAR', true, 255, null); + $this->addColumn('ATTRIBUTE_CHAPO', 'AttributeChapo', 'LONGVARCHAR', false, null, null); + $this->addColumn('ATTRIBUTE_DESCRIPTION', 'AttributeDescription', 'CLOB', false, null, null); + $this->addColumn('ATTRIBUTE_POSTSCRIPTUMN', 'AttributePostscriptumn', 'LONGVARCHAR', false, null, null); + $this->addColumn('ATTRIBUTE_AV_TITLE', 'AttributeAvTitle', 'VARCHAR', true, 255, null); + $this->addColumn('ATTRIBUTE_AV_CHAPO', 'AttributeAvChapo', 'LONGVARCHAR', false, null, null); + $this->addColumn('ATTRIBUTE_AV_DESCRIPTION', 'AttributeAvDescription', 'CLOB', false, null, null); + $this->addColumn('ATTRIBUTE_AV_POSTSCRIPTUM', 'AttributeAvPostscriptum', 'LONGVARCHAR', false, 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('OrderProduct', '\\Thelia\\Model\\OrderProduct', RelationMap::MANY_TO_ONE, array('order_product_id' => 'id', ), 'CASCADE', 'RESTRICT'); + } // 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 ? OrderProductAttributeCombinationTableMap::CLASS_DEFAULT : OrderProductAttributeCombinationTableMap::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 (OrderProductAttributeCombination object, last column rank) + */ + public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $key = OrderProductAttributeCombinationTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = OrderProductAttributeCombinationTableMap::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 + OrderProductAttributeCombinationTableMap::NUM_HYDRATE_COLUMNS; + } else { + $cls = OrderProductAttributeCombinationTableMap::OM_CLASS; + $obj = new $cls(); + $col = $obj->hydrate($row, $offset, false, $indexType); + OrderProductAttributeCombinationTableMap::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 = OrderProductAttributeCombinationTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = OrderProductAttributeCombinationTableMap::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; + OrderProductAttributeCombinationTableMap::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(OrderProductAttributeCombinationTableMap::ID); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ORDER_PRODUCT_ID); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_TITLE); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_CHAPO); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_DESCRIPTION); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_POSTSCRIPTUMN); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_TITLE); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_CHAPO); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_DESCRIPTION); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::ATTRIBUTE_AV_POSTSCRIPTUM); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::CREATED_AT); + $criteria->addSelectColumn(OrderProductAttributeCombinationTableMap::UPDATED_AT); + } else { + $criteria->addSelectColumn($alias . '.ID'); + $criteria->addSelectColumn($alias . '.ORDER_PRODUCT_ID'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_TITLE'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_CHAPO'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_DESCRIPTION'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_POSTSCRIPTUMN'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_AV_TITLE'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_AV_CHAPO'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_AV_DESCRIPTION'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_AV_POSTSCRIPTUM'); + $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(OrderProductAttributeCombinationTableMap::DATABASE_NAME)->getTable(OrderProductAttributeCombinationTableMap::TABLE_NAME); + } + + /** + * Add a TableMap instance to the database for this tableMap class. + */ + public static function buildTableMap() + { + $dbMap = Propel::getServiceContainer()->getDatabaseMap(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(OrderProductAttributeCombinationTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new OrderProductAttributeCombinationTableMap()); + } + } + + /** + * Performs a DELETE on the database, given a OrderProductAttributeCombination or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or OrderProductAttributeCombination 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(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + // rename for clarity + $criteria = $values; + } elseif ($values instanceof \Thelia\Model\OrderProductAttributeCombination) { // 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(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + $criteria->add(OrderProductAttributeCombinationTableMap::ID, (array) $values, Criteria::IN); + } + + $query = OrderProductAttributeCombinationQuery::create()->mergeWith($criteria); + + if ($values instanceof Criteria) { OrderProductAttributeCombinationTableMap::clearInstancePool(); + } elseif (!is_object($values)) { // it's a primary key, or an array of pks + foreach ((array) $values as $singleval) { OrderProductAttributeCombinationTableMap::removeInstanceFromPool($singleval); + } + } + + return $query->delete($con); + } + + /** + * Deletes all rows from the order_product_attribute_combination 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 OrderProductAttributeCombinationQuery::create()->doDeleteAll($con); + } + + /** + * Performs an INSERT on the database, given a OrderProductAttributeCombination or Criteria object. + * + * @param mixed $criteria Criteria or OrderProductAttributeCombination 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(OrderProductAttributeCombinationTableMap::DATABASE_NAME); + } + + if ($criteria instanceof Criteria) { + $criteria = clone $criteria; // rename for clarity + } else { + $criteria = $criteria->buildCriteria(); // build Criteria from OrderProductAttributeCombination object + } + + if ($criteria->containsKey(OrderProductAttributeCombinationTableMap::ID) && $criteria->keyContainsValue(OrderProductAttributeCombinationTableMap::ID) ) { + throw new PropelException('Cannot insert a value for auto-increment primary key ('.OrderProductAttributeCombinationTableMap::ID.')'); + } + + + // Set the correct dbName + $query = OrderProductAttributeCombinationQuery::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; + } + +} // OrderProductAttributeCombinationTableMap +// This is the static code needed to register the TableMap for this table with the main Propel class. +// +OrderProductAttributeCombinationTableMap::buildTableMap(); diff --git a/core/lib/Thelia/Model/Map/OrderProductTaxTableMap.php b/core/lib/Thelia/Model/Map/OrderProductTaxTableMap.php new file mode 100644 index 000000000..2e8460a6a --- /dev/null +++ b/core/lib/Thelia/Model/Map/OrderProductTaxTableMap.php @@ -0,0 +1,463 @@ + array('Id', 'OrderProductId', 'Title', 'Description', 'Amount', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'orderProductId', 'title', 'description', 'amount', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(OrderProductTaxTableMap::ID, OrderProductTaxTableMap::ORDER_PRODUCT_ID, OrderProductTaxTableMap::TITLE, OrderProductTaxTableMap::DESCRIPTION, OrderProductTaxTableMap::AMOUNT, OrderProductTaxTableMap::CREATED_AT, OrderProductTaxTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'ORDER_PRODUCT_ID', 'TITLE', 'DESCRIPTION', 'AMOUNT', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'order_product_id', 'title', 'description', 'amount', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) + ); + + /** + * 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, 'OrderProductId' => 1, 'Title' => 2, 'Description' => 3, 'Amount' => 4, 'CreatedAt' => 5, 'UpdatedAt' => 6, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'orderProductId' => 1, 'title' => 2, 'description' => 3, 'amount' => 4, 'createdAt' => 5, 'updatedAt' => 6, ), + self::TYPE_COLNAME => array(OrderProductTaxTableMap::ID => 0, OrderProductTaxTableMap::ORDER_PRODUCT_ID => 1, OrderProductTaxTableMap::TITLE => 2, OrderProductTaxTableMap::DESCRIPTION => 3, OrderProductTaxTableMap::AMOUNT => 4, OrderProductTaxTableMap::CREATED_AT => 5, OrderProductTaxTableMap::UPDATED_AT => 6, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'ORDER_PRODUCT_ID' => 1, 'TITLE' => 2, 'DESCRIPTION' => 3, 'AMOUNT' => 4, 'CREATED_AT' => 5, 'UPDATED_AT' => 6, ), + self::TYPE_FIELDNAME => array('id' => 0, 'order_product_id' => 1, 'title' => 2, 'description' => 3, 'amount' => 4, 'created_at' => 5, 'updated_at' => 6, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) + ); + + /** + * 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('order_product_tax'); + $this->setPhpName('OrderProductTax'); + $this->setClassName('\\Thelia\\Model\\OrderProductTax'); + $this->setPackage('Thelia.Model'); + $this->setUseIdGenerator(true); + // columns + $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); + $this->addForeignKey('ORDER_PRODUCT_ID', 'OrderProductId', 'INTEGER', 'order_product', 'ID', true, null, null); + $this->addColumn('TITLE', 'Title', 'VARCHAR', true, 255, null); + $this->addColumn('DESCRIPTION', 'Description', 'CLOB', false, null, null); + $this->addColumn('AMOUNT', 'Amount', 'FLOAT', 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('OrderProduct', '\\Thelia\\Model\\OrderProduct', RelationMap::MANY_TO_ONE, array('order_product_id' => 'id', ), 'CASCADE', 'RESTRICT'); + } // 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 ? OrderProductTaxTableMap::CLASS_DEFAULT : OrderProductTaxTableMap::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 (OrderProductTax object, last column rank) + */ + public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $key = OrderProductTaxTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = OrderProductTaxTableMap::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 + OrderProductTaxTableMap::NUM_HYDRATE_COLUMNS; + } else { + $cls = OrderProductTaxTableMap::OM_CLASS; + $obj = new $cls(); + $col = $obj->hydrate($row, $offset, false, $indexType); + OrderProductTaxTableMap::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 = OrderProductTaxTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = OrderProductTaxTableMap::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; + OrderProductTaxTableMap::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(OrderProductTaxTableMap::ID); + $criteria->addSelectColumn(OrderProductTaxTableMap::ORDER_PRODUCT_ID); + $criteria->addSelectColumn(OrderProductTaxTableMap::TITLE); + $criteria->addSelectColumn(OrderProductTaxTableMap::DESCRIPTION); + $criteria->addSelectColumn(OrderProductTaxTableMap::AMOUNT); + $criteria->addSelectColumn(OrderProductTaxTableMap::CREATED_AT); + $criteria->addSelectColumn(OrderProductTaxTableMap::UPDATED_AT); + } else { + $criteria->addSelectColumn($alias . '.ID'); + $criteria->addSelectColumn($alias . '.ORDER_PRODUCT_ID'); + $criteria->addSelectColumn($alias . '.TITLE'); + $criteria->addSelectColumn($alias . '.DESCRIPTION'); + $criteria->addSelectColumn($alias . '.AMOUNT'); + $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(OrderProductTaxTableMap::DATABASE_NAME)->getTable(OrderProductTaxTableMap::TABLE_NAME); + } + + /** + * Add a TableMap instance to the database for this tableMap class. + */ + public static function buildTableMap() + { + $dbMap = Propel::getServiceContainer()->getDatabaseMap(OrderProductTaxTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(OrderProductTaxTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new OrderProductTaxTableMap()); + } + } + + /** + * Performs a DELETE on the database, given a OrderProductTax or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or OrderProductTax 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(OrderProductTaxTableMap::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + // rename for clarity + $criteria = $values; + } elseif ($values instanceof \Thelia\Model\OrderProductTax) { // 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(OrderProductTaxTableMap::DATABASE_NAME); + $criteria->add(OrderProductTaxTableMap::ID, (array) $values, Criteria::IN); + } + + $query = OrderProductTaxQuery::create()->mergeWith($criteria); + + if ($values instanceof Criteria) { OrderProductTaxTableMap::clearInstancePool(); + } elseif (!is_object($values)) { // it's a primary key, or an array of pks + foreach ((array) $values as $singleval) { OrderProductTaxTableMap::removeInstanceFromPool($singleval); + } + } + + return $query->delete($con); + } + + /** + * Deletes all rows from the order_product_tax 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 OrderProductTaxQuery::create()->doDeleteAll($con); + } + + /** + * Performs an INSERT on the database, given a OrderProductTax or Criteria object. + * + * @param mixed $criteria Criteria or OrderProductTax 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(OrderProductTaxTableMap::DATABASE_NAME); + } + + if ($criteria instanceof Criteria) { + $criteria = clone $criteria; // rename for clarity + } else { + $criteria = $criteria->buildCriteria(); // build Criteria from OrderProductTax object + } + + if ($criteria->containsKey(OrderProductTaxTableMap::ID) && $criteria->keyContainsValue(OrderProductTaxTableMap::ID) ) { + throw new PropelException('Cannot insert a value for auto-increment primary key ('.OrderProductTaxTableMap::ID.')'); + } + + + // Set the correct dbName + $query = OrderProductTaxQuery::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; + } + +} // OrderProductTaxTableMap +// This is the static code needed to register the TableMap for this table with the main Propel class. +// +OrderProductTaxTableMap::buildTableMap(); diff --git a/core/lib/Thelia/Model/OrderProductAttributeCombination.php b/core/lib/Thelia/Model/OrderProductAttributeCombination.php new file mode 100644 index 000000000..1f9cee13d --- /dev/null +++ b/core/lib/Thelia/Model/OrderProductAttributeCombination.php @@ -0,0 +1,10 @@ + +
+ + + + + {include + file="includes/inner-form-toolbar.html" + hide_submit_buttons=false + close_url="{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}" + } + +
+ {intl l="To use features or attributes on this product, please select a product template. You can define product templates in the Configuration section of the administration."} +
+ +
+
+ + +
+ + + + + +
+
+
+ + {ifloop rel="product_template"} + + {* -- Begin attributes management ----------------------------------- *} + +
+ {loop name="product_template" type="template" id={$TEMPLATE|default:0}}{/loop} + +
+
+

{intl l='Product Attributes'}

+

{intl l='You can attach here some content to this product'}

+
+
+
+ + {* -- End attributes management -------------------------------------- *} + + {* -- Begin features management -------------------------------------- *} + +
+
+
+ +

{intl l='Product Features'}

+

{intl l='Enter here product features'}

+ +
+ + + + + + + {module_include location='product_features_table_header'} + + + + + + {loop name="product-features" type="feature" order="manual" product="$product_id" backend_context="1" lang="$edit_language_id"} + + + + + + {module_include location='product_features_table_row'} + + + {/loop} + + {elseloop rel="product-features"} + + + + {/elseloop} + +
{intl l='Feature Name'}{intl l='Feature value for this product'}
{$TITLE} + {* Multiple values *} + + {ifloop rel="product-features-av"} + + {loop name="free-text-value" exclude_free_text="true" type="feature_value" product=$product_id feature=$ID backend_context="1" lang="$edit_language_id"} + value={$FEATURE_AV_ID}: {$TITLE}
+ {/loop} + + {capture "select_options"} + {loop name="product-features-av" type="feature-availability" feature=$ID order="manual" backend_context="1" lang="$edit_language_id"} + + {$options_count = $LOOP_COUNT} {* LOOP_COUNT is only available inside the loop ! *} + {/loop} + {/capture} + +
+ +
+ + + {intl l='Use ctrl+clic to select more than one value. You can also clear selected values.' id=$ID} + + + {/ifloop} + + {* Free feature *} + + {elseloop rel="product-features-av"} + {* Get the free text value *} + + {loop name="free-text-value" exclude_feature_availability="1" type="feature_value" product=$product_id feature=$ID backend_context="1" lang="$edit_language_id"} + {$feature_value=$FREE_TEXT_VALUE} + {/loop} + + + {/elseloop} +
+
+ {intl l="This product contains no features"} +
+
+
+
+
+ + {* -- End features management --------- *} + {/ifloop} +
+ + {elseloop rel="product_template"} +
+
+ +
+ {intl l="This product is not attached to any product template. If you want to use features or attributes on this product, please select the proper template. You can define product templates in the Configuration section."} +
+
+
+ {/elseloop} + +
+
diff --git a/templates/admin/default/includes/product-content-tab.html b/templates/admin/default/includes/product-content-tab.html new file mode 100644 index 000000000..e17517930 --- /dev/null +++ b/templates/admin/default/includes/product-content-tab.html @@ -0,0 +1,273 @@ +
+ + {include + file="includes/inner-form-toolbar.html" + hide_submit_buttons=true + close_url="{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}" + } + + {* -- Begin related content management -- *} + +
+
+ +
+ +
+ + + + + + + + {module_include location='product_contents_table_header'} + + + + + + + {loop name="assigned_contents" type="associated_content" product="$product_id" backend_context="1" lang="$edit_language_id"} + + + + + + {module_include location='product_contents_table_row'} + + + + {/loop} + + {elseloop rel="assigned_contents"} + + + + {/elseloop} + +
{intl l='ID'}{intl l='Content title'}{intl l="Actions"}
{$ID} + {$TITLE} + +
+ {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.product.content.delete"} + + + + {/loop} +
+
+
+ {intl l="This product contains no contents"} +
+
+
+
+ + {* -- End related content management ---- *} + + {* -- Begin accessories management ------ *} + +
+
+
+ +

{intl l='Product accessories'}

+

{intl l='Define here this product\'s accessories'}

+ + + + + {ifloop rel="categories"} +
+ + + {intl l='Select a category to get its products'} +
+ +
+
+ + + + +
+ + {intl l='Select a product and click (+) to add it as an accessory'} +
+ +
+
+ {intl l="No available product in this category"} +
+
+ + {/ifloop} + + {elseloop rel="categories"} +
{intl l="No categories found"}
+ {/elseloop} + +
+
+ +
+ + + + + + + + + + {module_include location='product_accessories_table_header'} + + + + + + + {loop name="assigned_accessories" order="accessory" type="accessory" product="$product_id" backend_context="1" lang="$edit_language_id"} + + + + + + + + {module_include location='product_accessories_table_row'} + + + + {/loop} + + {elseloop rel="assigned_accessories"} + + + + {/elseloop} + +
{intl l='ID'}{intl l='Accessory title'}{intl l='Position'}{intl l="Actions"}
{$ID} + {$TITLE} + + {admin_position_block + permission="admin.products.edit" + path={url path='/admin/products/update-accessory-position' product_id=$ID} + url_parameter="accessory_id" + in_place_edit_class="accessoryPositionChange" + position=$POSITION + id=$ID + } + +
+ {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.product.accessory.delete"} + + + + {/loop} +
+
+
+ {intl l="This product contains no accessories"} +
+
+
+
+ + {* -- End accessories management -------- *} + +
+ +{* Delete related content confirmation dialog *} + +{capture "delete_content_dialog"} + + + + + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "delete_content_dialog" + dialog_title = {intl l="Remove related content"} + dialog_message = {intl l="Do you really want to remove this related content from the product ?"} + + form_action = {url path='/admin/products/related-content/delete'} + form_content = {$smarty.capture.delete_content_dialog nofilter} +} + +{* Delete accessory confirmation dialog *} + +{capture "delete_accessory_dialog"} + + + + + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "delete_accessory_dialog" + dialog_title = {intl l="Remove an accessory"} + dialog_message = {intl l="Do you really want to remove this accessory from the product ?"} + + form_action = {url path='/admin/products/accessory/delete'} + form_content = {$smarty.capture.delete_accessory_dialog nofilter} +} \ No newline at end of file diff --git a/templates/admin/default/includes/product-general-tab.html b/templates/admin/default/includes/product-general-tab.html new file mode 100644 index 000000000..792d09ad9 --- /dev/null +++ b/templates/admin/default/includes/product-general-tab.html @@ -0,0 +1,97 @@ +
+ + {form name="thelia.admin.product.modification"} +
+ + {include file="includes/inner-form-toolbar.html" close_url="{url path='/admin/products' product_id=$product_id}"} + + {* Be sure to get the product 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} + +
+ + +
{$REF}
+
+ + {include file="includes/standard-description-form-fields.html"} + + {form_field form=$form field='url'} +
+ + + +
+ {/form_field} + +
+
+ + {form_field form=$form field='default_category'} +
+ + + + + {intl l='You can attach this product to more categories in the details tab.'} +
+ {/form_field} + +
+ +
+ {form_field form=$form field='visible'} +
+ +
+ +
+
+ {/form_field} +
+
+ +
+
+
+   +
+

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

+
+
+
+
+ +
+ {/form} +
From ced7b5e6dccaa80cd5c5b6ba2fed4ec96bed78f7 Mon Sep 17 00:00:00 2001 From: gmorel Date: Fri, 20 Sep 2013 16:51:34 +0200 Subject: [PATCH 04/43] WIP : Upload management (upload+save+delete done) need to finish integration and add all image fields --- core/lib/Thelia/Action/BaseAction.php | 15 + core/lib/Thelia/Action/Image.php | 120 +++++- core/lib/Thelia/Config/Resources/config.xml | 7 +- .../Thelia/Config/Resources/routing/admin.xml | 13 + .../Controller/Admin/CategoryController.php | 30 +- .../Controller/Admin/FileController.php | 290 ++++++++++++++ .../Core/Event/ImageCreateOrUpdateEvent.php | 184 +++++++++ .../Thelia/Core/Event/ImageDeleteEvent.php | 82 ++++ core/lib/Thelia/Core/Event/TheliaEvents.php | 10 + .../Template/Smarty/Plugins/FlashMessage.php | 103 +++++ .../Thelia/Form/CategoryImageCreationForm.php | 71 ++++ .../Form/CategoryPictureCreationForm.php | 100 ----- .../Thelia/Form/Type/ImageCategoryType.php | 79 ++++ core/lib/Thelia/Form/Type/ImageType.php | 82 ++++ core/lib/Thelia/Model/CategoryImage.php | 30 +- core/lib/Thelia/Model/ContentImage.php | 10 + core/lib/Thelia/Model/FolderImage.php | 10 + core/lib/Thelia/Model/ProductImage.php | 10 + .../Thelia/Tests/Tools/FileManagerTest.php | 361 ++++++++++++++++++ core/lib/Thelia/Tools/FileManager.php | 222 +++++++++++ core/lib/Thelia/Tools/I18n.php | 1 + .../admin/default/assets/js/image-upload.js | 67 ++++ templates/admin/default/category-edit.html | 29 +- .../default/includes/image-upload-form.html | 80 ++++ 24 files changed, 1838 insertions(+), 168 deletions(-) create mode 100755 core/lib/Thelia/Controller/Admin/FileController.php create mode 100755 core/lib/Thelia/Core/Event/ImageCreateOrUpdateEvent.php create mode 100755 core/lib/Thelia/Core/Event/ImageDeleteEvent.php create mode 100755 core/lib/Thelia/Core/Template/Smarty/Plugins/FlashMessage.php create mode 100644 core/lib/Thelia/Form/CategoryImageCreationForm.php delete mode 100644 core/lib/Thelia/Form/CategoryPictureCreationForm.php create mode 100644 core/lib/Thelia/Form/Type/ImageCategoryType.php create mode 100644 core/lib/Thelia/Form/Type/ImageType.php create mode 100644 core/lib/Thelia/Tests/Tools/FileManagerTest.php create mode 100644 core/lib/Thelia/Tools/FileManager.php create mode 100644 templates/admin/default/assets/js/image-upload.js create mode 100644 templates/admin/default/includes/image-upload-form.html diff --git a/core/lib/Thelia/Action/BaseAction.php b/core/lib/Thelia/Action/BaseAction.php index 56565ddc6..6aceb033a 100755 --- a/core/lib/Thelia/Action/BaseAction.php +++ b/core/lib/Thelia/Action/BaseAction.php @@ -23,6 +23,7 @@ namespace Thelia\Action; use Symfony\Component\DependencyInjection\ContainerInterface; +use Thelia\Model\AdminLog; class BaseAction { @@ -45,4 +46,18 @@ class BaseAction { return $this->container->get('event_dispatcher'); } + + /** + * Helper to append a message to the admin log. + * + * @param string $message + */ + public function adminLogAppend($message) + { + AdminLog::append( + $message, + $this->container->get('request'), + $this->container->get('thelia.securityContext')->getAdminUser() + ); + } } diff --git a/core/lib/Thelia/Action/Image.php b/core/lib/Thelia/Action/Image.php index 4660f93b8..41ce957d4 100755 --- a/core/lib/Thelia/Action/Image.php +++ b/core/lib/Thelia/Action/Image.php @@ -23,10 +23,19 @@ namespace Thelia\Action; +use Propel\Runtime\ActiveRecord\ActiveRecordInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpFoundation\File\UploadedFile; +use Thelia\Core\Event\ImageCreateOrUpdateEvent; +use Thelia\Core\Event\ImageDeleteEvent; use Thelia\Core\Event\ImageEvent; +use Thelia\Model\CategoryImage; use Thelia\Model\ConfigQuery; +use Thelia\Model\ContentImage; +use Thelia\Model\FolderImage; +use Thelia\Model\ProductImage; +use Thelia\Tools\FileManager; use Thelia\Tools\URL; use Imagine\Image\ImagineInterface; @@ -39,10 +48,10 @@ use Thelia\Core\Event\TheliaEvents; /** * - * Image management actions. This class handles image processing an caching. + * Image management actions. This class handles image processing and caching. * - * Basically, images are stored outside the web space (by default in local/media/images), - * and cached in the web space (by default in web/local/images). + * Basically, images are stored outside of the web space (by default in local/media/images), + * and cached inside the web space (by default in web/local/images). * * In the images caches directory, a subdirectory for images categories (eg. product, category, folder, etc.) is * automatically created, and the cached image is created here. Plugin may use their own subdirectory as required. @@ -78,6 +87,8 @@ class Image extends BaseCachedFile implements EventSubscriberInterface const EXACT_RATIO_WITH_CROP = 2; const KEEP_IMAGE_RATIO = 3; + + /** * @return string root of the image cache directory in web space */ @@ -240,6 +251,107 @@ class Image extends BaseCachedFile implements EventSubscriberInterface $event->setOriginalFileUrl(URL::getInstance()->absoluteUrl($original_image_url, null, URL::PATH_TO_FILE)); } + /** + * Take care of saving images in the database and file storage + * + * @param ImageCreateOrUpdateEvent $event Image event + * + * @throws \Thelia\Exception\ImageException + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + */ + public function saveImages(ImageCreateOrUpdateEvent $event) + { + $fileManager = new FileManager($this->container); + + $this->adminLogAppend( + $this->container->get('thelia.translator')->trans( + 'Saving images for parent id %parentId% (%parentType%)', + array( + '%parentId%' => $event->getParentId(), + '%parentType%' => $event->getImageType() + ), + 'image' + ) + ); + + $newUploadedFiles = array(); + $uploadedFiles = $event->getUploadedFiles(); + + foreach ($event->getModelImages() as $i => $modelImage) { + // Save image to database in order to get image id + $fileManager->saveImage($event, $modelImage); + + if (isset($uploadedFiles) && isset($uploadedFiles[$i])) { + /** @var UploadedFile $uploadedFile */ + $uploadedFile = $uploadedFiles[$i]['file']; + + // Copy uploaded file into the storage directory + $newUploadedFiles = $fileManager->copyUploadedFile($event->getParentId(), $event->getImageType(), $modelImage, $uploadedFile, $newUploadedFiles); + } else { + throw new ImageException( + sprintf( + 'File with name %s not found on the server', + $modelImage->getFile() + ) + ); + } + $event->setUploadedFiles($newUploadedFiles); + } + } + + /** + * Take care of deleting image in the database and file storage + * + * @param ImageCreateOrUpdateEvent $event Image event + * + * @throws \Thelia\Exception\ImageException + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + */ + public function deleteImage(ImageDeleteEvent $event) + { + $fileManager = new FileManager($this->container); + + try { + $fileManager->deleteImage($event->getImageToDelete()); + + $this->adminLogAppend( + $this->container->get('thelia.translator')->trans( + 'Deleting image for %id% with parent id %parentId%', + array( + '%id%' => $event->getImageToDelete()->getId(), + '%parentId%' => $event->getImageToDelete()->getParentId(), + ), + 'image' + ) + ); + } catch(\Exception $e) { + $this->adminLogAppend( + $this->container->get('thelia.translator')->trans( + 'Fail to delete image for %id% with parent id %parentId% (Exception : %e%)', + array( + '%id%' => $event->getImageToDelete()->getId(), + '%parentId%' => $event->getImageToDelete()->getParentId(), + '%e%' => $e->getMessage() + ), + 'image' + ) + ); + } + } + + /** + * The absolute directory path where uploaded + * documents should be saved + * + * @param $modelImage Image model + * + * @return string + */ + public function getUploadRootDir($modelImage) + { + return __DIR__.'/../../../../' . $modelImage->getUploadDir(); + } + /** * Process image resizing, with borders or cropping. If $dest_width and $dest_height * are both null, no resize is performed. @@ -362,6 +474,8 @@ class Image extends BaseCachedFile implements EventSubscriberInterface return array( TheliaEvents::IMAGE_PROCESS => array("processImage", 128), TheliaEvents::IMAGE_CLEAR_CACHE => array("clearCache", 128), + TheliaEvents::IMAGE_SAVE => array("saveImages", 128), + TheliaEvents::IMAGE_DELETE => array("deleteImage", 128), ); } } diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index db2b1db82..bdf6a01e0 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -54,7 +54,7 @@
- + @@ -225,6 +225,11 @@ + + + + + diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 8f2e54f86..0fbf38696 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -31,6 +31,19 @@ Thelia\Controller\Admin\CategoryController::defaultAction + + + + Thelia\Controller\Admin\FileController::saveImagesAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::deleteImagesAction + .* + \d+ + + diff --git a/core/lib/Thelia/Controller/Admin/CategoryController.php b/core/lib/Thelia/Controller/Admin/CategoryController.php index 1c7854416..34d7a5f04 100755 --- a/core/lib/Thelia/Controller/Admin/CategoryController.php +++ b/core/lib/Thelia/Controller/Admin/CategoryController.php @@ -23,11 +23,13 @@ namespace Thelia\Controller\Admin; +use Symfony\Component\HttpFoundation\Response; use Thelia\Core\Event\CategoryDeleteEvent; +use Thelia\Core\Event\ImageCreateOrUpdateEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\CategoryUpdateEvent; use Thelia\Core\Event\CategoryCreateEvent; -use Thelia\Form\CategoryPictureCreationForm; +use Thelia\Log\Tlog; use Thelia\Model\CategoryQuery; use Thelia\Form\CategoryModificationForm; use Thelia\Form\CategoryCreationForm; @@ -35,7 +37,6 @@ use Thelia\Core\Event\UpdatePositionEvent; use Thelia\Core\Event\CategoryToggleVisibilityEvent; use Thelia\Core\Event\CategoryDeleteContentEvent; use Thelia\Core\Event\CategoryAddContentEvent; -use Thelia\Model\CategoryAssociatedContent; use Thelia\Model\FolderQuery; use Thelia\Model\ContentQuery; use Propel\Runtime\ActiveQuery\Criteria; @@ -366,29 +367,4 @@ class CategoryController extends AbstractCrudController $this->redirectToEditionTemplate(); } - /** - * @todo remove - * @return Symfony\Component\HttpFoundation\Response|void - */ - public function updateAction() - { - var_dump('updateAction'); - if ($this->getRequest()->isMethod('POST')) { - var_dump('getRequest', $this->getRequest()->files); - // Create the form from the request - $creationForm = new CategoryPictureCreationForm($this->getRequest()); - - // Check the form against constraints violations - $form = $this->validateForm($creationForm, 'POST'); - var_dump('$form', $form); - - // Get the form field values - $data = $form->getData(); - var_dump('$data', $data); - } - - - return parent::updateAction(); - } - } diff --git a/core/lib/Thelia/Controller/Admin/FileController.php b/core/lib/Thelia/Controller/Admin/FileController.php new file mode 100755 index 000000000..4be913bcb --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/FileController.php @@ -0,0 +1,290 @@ +. */ +/* */ +/**********************************************************************************/ + +namespace Thelia\Controller\Admin; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Router; +use Thelia\Core\Event\ImageCreateOrUpdateEvent; +use Thelia\Core\Event\ImageDeleteEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Core\Translation\Translator; +use Thelia\Form\CategoryImageCreationForm; +use Thelia\Form\Exception\FormValidationException; +use Thelia\Log\Tlog; +use Thelia\Model\CategoryImageQuery; +use Thelia\Model\ContentImageQuery; +use Thelia\Model\FolderImageQuery; +use Thelia\Model\ProductImageQuery; + +/** + * Created by JetBrains PhpStorm. + * Date: 8/19/13 + * Time: 3:24 PM + * + * Control View and Action (Model) via Events + * Control Files and Images + * + * @package File + * @author Guillaume MOREL + * + */ +class FileController extends BaseAdminController +{ + /** + * Manage how a file collection has to be saved + * + * @param int $parentId Parent id owning files being saved + * @param string $parentType Parent Type owning files being saved + * @param string $successUrl Success URL to be redirected to + * + * @return Response + */ + public function saveFilesAction($parentId, $parentType, $successUrl) + { + + } + + /** + * Manage how a image collection has to be saved + * + * @param int $parentId Parent id owning images being saved + * @param string $parentType Parent Type owning images being saved + * + * @return Response + */ + public function saveImagesAction($parentId, $parentType) + { + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.image.save")) { + return $response; + } + + $message = $this->getTranslator() + ->trans( + 'Images saved successfully', + array(), + 'image' + ); + + if ($this->isParentTypeValid($parentType)) { + if ($this->getRequest()->isMethod('POST')) { + // Create the form from the request + $creationForm = $this->getImageForm($parentType, $this->getRequest()); + + try { + // Check the form against constraints violations + $form = $this->validateForm($creationForm, 'POST'); + + // Get the form field values + $data = $form->getData(); + + // Feed event + $imageCreateOrUpdateEvent = new ImageCreateOrUpdateEvent( + $parentType, + $parentId + ); + if (isset($data) && isset($data['pictures'])) { + $imageCreateOrUpdateEvent->setModelImages($data['pictures']); + $imageCreateOrUpdateEvent->setUploadedFiles($this->getRequest()->files->get($creationForm->getName())['pictures']); + } + + // Dispatch Event to the Action + $this->dispatch( + TheliaEvents::IMAGE_SAVE, + $imageCreateOrUpdateEvent + ); + + } catch (FormValidationException $e) { + // Invalid data entered + $message = 'Please check your input:'; + $this->logError($parentType, 'image saving', $message, $e); + + } catch (\Exception $e) { + // Any other error + $message = 'Sorry, an error occurred:'; + $this->logError($parentType, 'image saving', $message, $e); + } + + if ($message !== false) { + // Mark the form as with error + $creationForm->setErrorMessage($message); + + // Send the form and the error to the parser + $this->getParserContext() + ->addForm($creationForm) + ->setGeneralError($message); + + // Set flash message to be displayed + $flashMessage = $this->getSession()->get('flashMessage'); + $flashMessage['imageMessage'] = $message; + $this->getSession()->set('flashMessage', $flashMessage); + } + } + } + + $this->redirectSuccess($creationForm); + } + + /** + * Manage how a image has to be deleted (AJAX) + * + * @param int $imageId Parent id owning images being saved + * @param string $parentType Parent Type owning images being saved + * + * @return Response + */ + public function deleteImagesAction($imageId, $parentType) + { + $this->checkAuth('ADMIN', 'admin.image.delete'); + $this->checkXmlHttpRequest(); + + $model = $this->getImageModel($parentType, $imageId); + if ($model == null) { + return $this->pageNotFound(); + } + + // Feed event + $imageDeleteEvent = new ImageDeleteEvent( + $model + ); + + // Dispatch Event to the Action + $this->dispatch( + TheliaEvents::IMAGE_DELETE, + $imageDeleteEvent + ); + + $message = $this->getTranslator() + ->trans( + 'Images deleted successfully', + array(), + 'image' + ); + + return new Response($message); + } + + /** + * Log error message + * + * @param string $parentType Parent type + * @param string $action Creation|Update|Delete + * @param string $message Message to log + * @param \Exception $e Exception to log + * + * @return $this + */ + protected function logError($parentType, $action, $message, $e) + { + Tlog::getInstance()->error( + sprintf( + 'Error during ' . $parentType . ' ' . $action . ' process : %s. Exception was %s', + $message, + $e->getMessage() + ) + ); + + return $this; + } + + /** + * Check if parent type is valid or not + * + * @param string $parentType Parent type + * + * @return bool + */ + public function isParentTypeValid($parentType) + { + return (in_array($parentType, ImageCreateOrUpdateEvent::getAvailableType())); + } + + /** + * Get Image form + * + * @param string $parentType Parent type + * @param Request $request Request Service + * + * @return null|CategoryImageCreationForm|ContentImageCreationForm|FolderImageCreationForm|ProductImageCreationForm + * + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + */ + public function getImageForm($parentType, Request $request) + { + // @todo implement other forms + switch ($parentType) { +// case ImageCreateOrUpdateEvent::TYPE_PRODUCT: +// $creationForm = new ProductImageCreationForm($request); +// break; + case ImageCreateOrUpdateEvent::TYPE_CATEGORY: + $creationForm = new CategoryImageCreationForm($request); + break; +// case ImageCreateOrUpdateEvent::TYPE_CONTENT: +// $creationForm = new ContentImageCreationForm($request); +// break; +// case ImageCreateOrUpdateEvent::TYPE_FOLDER: +// $creationForm = new FolderImageCreationForm($request); +// break; + default: + $creationForm = null; + } + + return $creationForm; + + } + + /** + * Get image model from type + * + * @param string $parentType + * @param int $imageId + * + * @return null|\Thelia\Model\CategoryImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage|\Thelia\Model\ProductImage + * + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + */ + public function getImageModel($parentType, $imageId) + { + switch ($parentType) { + case ImageCreateOrUpdateEvent::TYPE_PRODUCT: + $model = ProductImageQuery::create()->findPk($imageId); + break; + case ImageCreateOrUpdateEvent::TYPE_CATEGORY: + $model = CategoryImageQuery::create()->findPk($imageId); + break; + case ImageCreateOrUpdateEvent::TYPE_CONTENT: + $model = ContentImageQuery::create()->findPk($imageId); + break; + case ImageCreateOrUpdateEvent::TYPE_FOLDER: + $model = FolderImageQuery::create()->findPk($imageId); + break; + default: + $model = null; + } + + return $model; + + } +} diff --git a/core/lib/Thelia/Core/Event/ImageCreateOrUpdateEvent.php b/core/lib/Thelia/Core/Event/ImageCreateOrUpdateEvent.php new file mode 100755 index 000000000..afae53e7a --- /dev/null +++ b/core/lib/Thelia/Core/Event/ImageCreateOrUpdateEvent.php @@ -0,0 +1,184 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Occurring when a Image list is saved + * + * @package Image + * @author Guillaume MOREL + * + */ +class ImageCreateOrUpdateEvent extends ActionEvent +{ + CONST TYPE_PRODUCT = 'product'; + CONST TYPE_CATEGORY = 'category'; + CONST TYPE_CONTENT = 'content'; + CONST TYPE_FOLDER = 'folder'; + + /** @var array Images model to save */ + protected $modelImages = array(); + + /** @var array Images file to save */ + protected $uploadedFiles = array(); + + /** @var int Image parent id */ + protected $parentId = null; + + /** @var string Image type */ + protected $imageType = null; + + /** @var array Available image parent type */ + protected static $availableType = array( + self::TYPE_PRODUCT, + self::TYPE_CATEGORY, + self::TYPE_CONTENT, + self::TYPE_FOLDER, + ); + + /** + * Constructor + * + * @param string $pictureType Picture type + * ex : ImageCreateOrUpdateEvent::TYPE_CATEGORY + * @param int $parentId Image parent id + */ + public function __construct($pictureType, $parentId) + { + $this->imageType = $pictureType; + $this->parentId = $parentId; + } + + /** + * Set Images to save + * + * @param array $images Thelia\Model\CategoryImage Array + * + * @return $this + */ + public function setModelImages($images) + { + $this->modelImages = $images; + + return $this; + } + + /** + * Get Images being saved + * + * @return array Array of Thelia\Model\CategoryImage + */ + public function getModelImages() + { + return $this->modelImages; + } + + /** + * Set Images to save + * + * @param array $images Thelia\Model\CategoryImage Array + * + * @return $this + */ + public function setUploadedFiles($images) + { + $this->uploadedFiles = $images; + + return $this; + } + + /** + * Get Images being saved + * + * @return array Array of Thelia\Model\CategoryImage + */ + public function getUploadedFiles() + { + return $this->uploadedFiles; + } + + /** + * Set picture type + * + * @param string $pictureType Picture type + * + * @return $this + */ + public function setImageType($pictureType) + { + $this->imageType = $pictureType; + + return $this; + } + + /** + * Get picture type + * + * @return string + */ + public function getImageType() + { + return $this->imageType; + } + + /** + * Get all image parent type available + * + * @return array + */ + public static function getAvailableType() + { + return self::$availableType; + } + + /** + * Set Image parent id + * + * @param int $parentId Image parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->parentId = $parentId; + + return $this; + } + + /** + * Get Image parent id + * + * @return int + */ + public function getParentId() + { + return $this->parentId; + } + + +} diff --git a/core/lib/Thelia/Core/Event/ImageDeleteEvent.php b/core/lib/Thelia/Core/Event/ImageDeleteEvent.php new file mode 100755 index 000000000..54e042e79 --- /dev/null +++ b/core/lib/Thelia/Core/Event/ImageDeleteEvent.php @@ -0,0 +1,82 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +use Thelia\Model\CategoryImage; +use Thelia\Model\ContentImage; +use Thelia\Model\FolderImage; +use Thelia\Model\ProductImage; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Occurring when a Image is about to be deleted + * + * @package Image + * @author Guillaume MOREL + * + */ +class ImageDeleteEvent extends ActionEvent +{ + /** @var CategoryImage|ProductImage|ContentImage|FolderImage Image about to be deleted */ + protected $imageToDelete = null; + + /** + * Constructor + * + * @param CategoryImage|ProductImage|ContentImage|FolderImage $imageToDelete Image about to be deleted + */ + public function __construct($imageToDelete) + { + $this->imageToDelete = $imageToDelete; + } + + /** + * Set Image about to be deleted + * + * @param CategoryImage|ProductImage|ContentImage|FolderImage $imageToDelete Image about to be deleted + * + * @return $this + */ + public function setImageToDelete($imageToDelete) + { + $this->imageToDelete = $imageToDelete; + + return $this; + } + + /** + * Get Image about to be deleted + * + * @return CategoryImage|ProductImage|ContentImage|FolderImage + */ + public function getImageToDelete() + { + return $this->imageToDelete; + } + + +} diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index dab2db208..2450143e7 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -234,6 +234,16 @@ final class TheliaEvents */ const IMAGE_CLEAR_CACHE = "action.clearImageCache"; + /** + * Save given images + */ + const IMAGE_SAVE = "action.saveImages"; + + /** + * Delete given image + */ + const IMAGE_DELETE = "action.deleteImage"; + /** * Sent when creating a Coupon */ diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/FlashMessage.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/FlashMessage.php new file mode 100755 index 000000000..569aedb84 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/FlashMessage.php @@ -0,0 +1,103 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Core\Template\Smarty\Plugins; + +use Symfony\Component\Form\FormView; +use Thelia\Form\BaseForm; +use Thelia\Core\Template\Element\Exception\ElementNotFoundException; +use Symfony\Component\HttpFoundation\Request; +use Thelia\Core\Template\Smarty\SmartyPluginDescriptor; +use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; +use Thelia\Core\Template\ParserContext; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Plugin for smarty defining blocks allowing to get flash message + * A flash message is a variable, array, object stored in session under the flashMessage key + * ex $SESSION['flashMessage']['myKey'] + * + * blocks : + * - {flashMessage key="myKey"} ... {/flashMessage} + * + * Class Form + * + * @package Thelia\Core\Template\Smarty\Plugins + * @author Guillaume MOREL + */ +class FlashMessage extends AbstractSmartyPlugin +{ + + /** @var Request Request service */ + protected $request; + + /** + * Constructor + * + * @param Request $request Request service + */ + public function __construct(Request $request) + { + $this->request = $request; + } + + /** + * Get FlashMessage + * And clean session from this key + * + * @param array $params Block parameters + * @param mixed $content Block content + * @param \Smarty_Internal_Template $template Template + * @param bool $repeat Control how many times + * the block is displayed + * + * @return mixed + */ + public function getFlashMessage($params, $content, \Smarty_Internal_Template $template, &$repeat) + { + if ($repeat) { + $key = $params['key']; + $flashBag = $this->request->getSession()->get('flashMessage'); + $template->assign('value', $flashBag[$key]); + + // Reset flash message (can be read once) + unset($flashBag[$key]); + $this->request->getSession()->set('flashMessage', $flashBag); + } else { + return $content; + } + } + + /** + * @return array an array of SmartyPluginDescriptor + */ + public function getPluginDescriptors() + { + return array( + new SmartyPluginDescriptor("block", "flashMessage", $this, "getFlashMessage") + ); + } + +} diff --git a/core/lib/Thelia/Form/CategoryImageCreationForm.php b/core/lib/Thelia/Form/CategoryImageCreationForm.php new file mode 100644 index 000000000..d0b3be229 --- /dev/null +++ b/core/lib/Thelia/Form/CategoryImageCreationForm.php @@ -0,0 +1,71 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Thelia\Core\Translation\Translator; +use Thelia\Form\Type\ImageCategoryType; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process an image collection + * + * @package Image + * @author Guillaume MOREL + * + */ +class CategoryImageCreationForm extends BaseForm +{ + /** + * Allow to build a form + */ + protected function buildForm() + { + $this->formBuilder + ->add('pictures', + 'collection', + array( + 'type' => new ImageCategoryType(), + 'options' => array( + 'required' => false + ), + 'allow_add' => true, + 'allow_delete' => true, + 'by_reference' => false, + ) + ) + ->add('formSuccessUrl'); + } + + /** + * Get form name + * + * @return string + */ + public function getName() + { + return 'thelia_category_image_creation'; + } +} diff --git a/core/lib/Thelia/Form/CategoryPictureCreationForm.php b/core/lib/Thelia/Form/CategoryPictureCreationForm.php deleted file mode 100644 index 2dffc61c3..000000000 --- a/core/lib/Thelia/Form/CategoryPictureCreationForm.php +++ /dev/null @@ -1,100 +0,0 @@ -. */ -/* */ -/*************************************************************************************/ -namespace Thelia\Form; - -use Symfony\Component\Validator\Constraints\Image; -use Symfony\Component\Validator\Constraints\NotBlank; -use Thelia\Core\Translation\Translator; - -class CategoryPictureCreationForm extends BaseForm -{ - protected function buildForm() - { - $this->formBuilder -// ->add('alt') - ->add('file', 'file', array( - 'constraints' => array( - new NotBlank(), - new Image( - array( - 'minWidth' => 200, - 'maxWidth' => 400, - 'minHeight' => 200, - 'maxHeight' => 400, - ) - ) - ))) -// ->add('category_id', 'model', array( -// 'disabled' => false, -// 'class' => 'Thelia\Model\ProductImage' -// )) -// ->add('position', 'integer', array( -// 'constraints' => array( -// new NotBlank() -// ) -// )) - ->add('title', 'text', array( - 'constraints' => array( -// new NotBlank() - ), -// 'label' => Translator::getInstance()->trans('Category picture title *'), -// 'label_attr' => array( -// 'for' => 'title' -// ) - )) -// ->add('description', 'text', array( -// 'constraints' => array( -// new NotBlank() -// ), -// 'label' => Translator::getInstance()->trans('Category picture description *'), -// 'label_attr' => array( -// 'for' => 'description' -// ) -// )) -// ->add('chapo', 'text', array( -// 'constraints' => array( -// new NotBlank() -// ), -// 'label' => Translator::getInstance()->trans('Category picture chapo *'), -// 'label_attr' => array( -// 'for' => 'chapo' -// ) -// )) -// ->add('postscriptum', 'text', array( -// 'constraints' => array( -// new NotBlank() -// ), -// 'label' => Translator::getInstance()->trans('Category picture postscriptum *'), -// 'label_attr' => array( -// 'for' => 'postscriptum' -// ) -// )) - - ; - } - - public function getName() - { - return 'thelia_category_picture_creation'; - } -} diff --git a/core/lib/Thelia/Form/Type/ImageCategoryType.php b/core/lib/Thelia/Form/Type/ImageCategoryType.php new file mode 100644 index 000000000..7b8a3c474 --- /dev/null +++ b/core/lib/Thelia/Form/Type/ImageCategoryType.php @@ -0,0 +1,79 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form\Type; + +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolverInterface; +use Thelia\Form\Type\ImageType; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process a category picture + * + * @package Image + * @author Guillaume MOREL + * + */ +class ImageCategoryType extends ImageType +{ + /** + * Build a Picture form + * + * @param FormBuilderInterface $builder Form builder + * @param array $options Form options + */ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder->add('category_id', 'integer'); + + parent::buildForm($builder, $options); + } + + /** + * Set default options + * Map the form to the given Model + * + * @param OptionsResolverInterface $resolver Option resolver + */ + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults( + array( + 'data_class' => 'Thelia\Model\CategoryImage' + ) + ); + } + + /** + * Get form name + * + * @return string + */ + public function getName() + { + return 'thelia_category_picture_creation_type'; + } +} diff --git a/core/lib/Thelia/Form/Type/ImageType.php b/core/lib/Thelia/Form/Type/ImageType.php new file mode 100644 index 000000000..662e2b3f7 --- /dev/null +++ b/core/lib/Thelia/Form/Type/ImageType.php @@ -0,0 +1,82 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form\Type; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Validator\Constraints\Image; +use Symfony\Component\Validator\Constraints\NotBlank; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process a picture + * + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + * + * @package Image + * @author Guillaume MOREL + * + */ +abstract class ImageType extends AbstractType +{ + /** + * Build a Picture form + * + * @param FormBuilderInterface $builder Form builder + * @param array $options Form options + */ + public function buildForm(FormBuilderInterface $builder, array $options) + { +// $builder->add('position'); + $builder->add( + 'title', + 'text', + array( + 'constraints' => new NotBlank() + ) + ); + $builder->add( + 'file', + 'file', + array( + 'constraints' => array( + new NotBlank(), + new Image( + array( + 'minWidth' => 200, +// 'maxWidth' => 400, + 'minHeight' => 200, +// 'maxHeight' => 400, + ) + ) + ) + ) + ); +// $builder->add('description'); +// $builder->add('chapo'); +// $builder->add('postscriptum'); + } +} diff --git a/core/lib/Thelia/Model/CategoryImage.php b/core/lib/Thelia/Model/CategoryImage.php index aca77615a..bb7fa0dcb 100755 --- a/core/lib/Thelia/Model/CategoryImage.php +++ b/core/lib/Thelia/Model/CategoryImage.php @@ -2,6 +2,8 @@ namespace Thelia\Model; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\HttpFoundation\File\UploadedFile; use Thelia\Model\Base\CategoryImage as BaseCategoryImage; use Propel\Runtime\Connection\ConnectionInterface; @@ -28,6 +30,7 @@ class CategoryImage extends BaseCategoryImage /** * Get picture absolute path + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action * * @return null|string */ @@ -35,11 +38,12 @@ class CategoryImage extends BaseCategoryImage { return null === $this->file ? null - : $this->getUploadRootDir().'/'.$this->file; + : $this->getUploadDir().'/'.$this->file; } /** * Get picture web path + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action * * @return null|string */ @@ -50,23 +54,25 @@ class CategoryImage extends BaseCategoryImage : $this->getUploadDir().'/'.$this->file; } - /** - * The absolute directory path where uploaded - * documents should be saved - * @return string - */ - protected function getUploadRootDir() - { - return __DIR__.'/../../../../../'.$this->getUploadDir(); - } /** * Get rid of the __DIR__ so it doesn't screw up * when displaying uploaded doc/image in the view. * @return string */ - protected function getUploadDir() + public function getUploadDir() { - return 'local/media/images/category'; + return THELIA_LOCAL_DIR . 'media/images/category'; } + + /** + * Get Image parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getCategoryId(); + } + } diff --git a/core/lib/Thelia/Model/ContentImage.php b/core/lib/Thelia/Model/ContentImage.php index ac1dcf755..ddb33cbe8 100755 --- a/core/lib/Thelia/Model/ContentImage.php +++ b/core/lib/Thelia/Model/ContentImage.php @@ -25,4 +25,14 @@ class ContentImage extends BaseContentImage return true; } + + /** + * Get Image parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getContentId(); + } } \ No newline at end of file diff --git a/core/lib/Thelia/Model/FolderImage.php b/core/lib/Thelia/Model/FolderImage.php index 58d8f928e..0983f0244 100755 --- a/core/lib/Thelia/Model/FolderImage.php +++ b/core/lib/Thelia/Model/FolderImage.php @@ -25,4 +25,14 @@ class FolderImage extends BaseFolderImage return true; } + + /** + * Get Image parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getFolderId(); + } } diff --git a/core/lib/Thelia/Model/ProductImage.php b/core/lib/Thelia/Model/ProductImage.php index 4bf0c40a6..058cbc863 100755 --- a/core/lib/Thelia/Model/ProductImage.php +++ b/core/lib/Thelia/Model/ProductImage.php @@ -25,4 +25,14 @@ class ProductImage extends BaseProductImage return true; } + + /** + * Get Image parent id + * + * @return int parent id + */ + public function getParentId() + { + return $this->getProductId(); + } } diff --git a/core/lib/Thelia/Tests/Tools/FileManagerTest.php b/core/lib/Thelia/Tests/Tools/FileManagerTest.php new file mode 100644 index 000000000..7ee1fd493 --- /dev/null +++ b/core/lib/Thelia/Tests/Tools/FileManagerTest.php @@ -0,0 +1,361 @@ + + */ + +namespace Thelia\Tests\Type; + + +use Thelia\Core\Event\ImageCreateOrUpdateEvent; +use Thelia\Exception\ImageException; +use Thelia\Model\Admin; +use Thelia\Model\ProductImage; +use Thelia\Tools\FileManager; + +class FileManagerTest extends \PHPUnit_Framework_TestCase { + + + /** + * @covers Thelia\Tools\FileManager::copyUploadedFile + */ + public function testCopyUploadedFile() + { + $this->markTestIncomplete( + 'Mock issue' + ); + + $stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator') + ->disableOriginalConstructor() + ->getMock(); + $stubTranslator->expects($this->any()) + ->method('trans') + ->will($this->returnValue('translated')); + + $stubRequest = $this->getMockBuilder('\Thelia\Core\HttpFoundation\Request') + ->disableOriginalConstructor() + ->getMock(); + + $stubSecurity = $this->getMockBuilder('\Thelia\Core\Security\SecurityContext') + ->disableOriginalConstructor() + ->getMock(); + $stubSecurity->expects($this->any()) + ->method('getAdminUser') + ->will($this->returnValue(new Admin())); + + + + // Create a map of arguments to return values. + $map = array( + array('thelia.translator', $stubTranslator), + array('request', $stubRequest), + array('thelia.securityContext', $stubSecurity) + ); + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + $stubContainer->expects($this->any()) + ->method('get') + ->will($this->returnValueMap($map)); + + $stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage') + ->disableOriginalConstructor() + ->getMock(); + $stubProductImage->expects($this->any()) + ->method('getUploadDir') + ->will($this->returnValue(THELIA_LOCAL_DIR . 'media/images/product')); + $stubProductImage->expects($this->any()) + ->method('getId') + ->will($this->returnValue(42)); + $stubProductImage->expects($this->any()) + ->method('setFile') + ->will($this->returnValue(true)); + $stubProductImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(0)); + + $stubUploadedFile = $this->getMockBuilder('\Symfony\Component\HttpFoundation\File\UploadedFile') + ->disableOriginalConstructor() + ->getMock(); + $stubUploadedFile->expects($this->any()) + ->method('getClientOriginalName') + ->will($this->returnValue('goodName')); + $stubUploadedFile->expects($this->any()) + ->method('getClientOriginalExtension') + ->will($this->returnValue('png')); + $stubUploadedFile->expects($this->any()) + ->method('move') + ->will($this->returnValue($stubUploadedFile)); + + $fileManager = new FileManager($stubContainer); + + $newUploadedFiles = array(); + + $actual = $fileManager->copyUploadedFile(24, ImageCreateOrUpdateEvent::TYPE_PRODUCT, $stubProductImage, $stubUploadedFile, $newUploadedFiles); + + $this->assertCount(1, $actual); + } + + + /** + * @covers Thelia\Tools\FileManager::copyUploadedFile + * @expectedException \Thelia\Exception\ImageException + */ + public function testCopyUploadedFileExceptionImageException() + { + $this->markTestIncomplete( + 'Mock issue' + ); + + $stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator') + ->disableOriginalConstructor() + ->getMock(); + $stubTranslator->expects($this->any()) + ->method('trans') + ->will($this->returnValue('translated')); + + $stubRequest = $this->getMockBuilder('\Thelia\Core\HttpFoundation\Request') + ->disableOriginalConstructor() + ->getMock(); + + $stubSecurity = $this->getMockBuilder('\Thelia\Core\Security\SecurityContext') + ->disableOriginalConstructor() + ->getMock(); + $stubSecurity->expects($this->any()) + ->method('getAdminUser') + ->will($this->returnValue(new Admin())); + + + + // Create a map of arguments to return values. + $map = array( + array('thelia.translator', $stubTranslator), + array('request', $stubRequest), + array('thelia.securityContext', $stubSecurity) + ); + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + $stubContainer->expects($this->any()) + ->method('get') + ->will($this->returnValueMap($map)); + + $stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage') + ->disableOriginalConstructor() + ->getMock(); + $stubProductImage->expects($this->any()) + ->method('getUploadDir') + ->will($this->returnValue(THELIA_LOCAL_DIR . 'media/images/product')); + $stubProductImage->expects($this->any()) + ->method('getId') + ->will($this->returnValue(42)); + $stubProductImage->expects($this->any()) + ->method('setFile') + ->will($this->returnValue(true)); + $stubProductImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(0)); + + $stubUploadedFile = $this->getMockBuilder('\Symfony\Component\HttpFoundation\File\UploadedFile') + ->disableOriginalConstructor() + ->getMock(); + $stubUploadedFile->expects($this->any()) + ->method('getClientOriginalName') + ->will($this->returnValue('goodName')); + $stubUploadedFile->expects($this->any()) + ->method('getClientOriginalExtension') + ->will($this->returnValue('png')); + $stubUploadedFile->expects($this->any()) + ->method('move') + ->will($this->returnValue($stubUploadedFile)); + + $fileManager = new FileManager($stubContainer); + + $newUploadedFiles = array(); + + $actual = $fileManager->copyUploadedFile(24, ImageCreateOrUpdateEvent::TYPE_PRODUCT, $stubProductImage, $stubUploadedFile, $newUploadedFiles); + + } + + /** + * @covers Thelia\Tools\FileManager::saveImage + */ + public function testSaveImageProductImage() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage') + ->disableOriginalConstructor() + ->getMock(); + $stubProductImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + + $fileManager = new FileManager($stubContainer); + + $event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_PRODUCT, 24); + + $expected = 10; + $actual = $fileManager->saveImage($event, $stubProductImage); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::saveImage + */ + public function testSaveImageCategoryImage() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $stubCategoryImage = $this->getMockBuilder('\Thelia\Model\CategoryImage') + ->disableOriginalConstructor() + ->getMock(); + $stubCategoryImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + + $fileManager = new FileManager($stubContainer); + + $event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_CATEGORY, 24); + + $expected = 10; + $actual = $fileManager->saveImage($event, $stubCategoryImage); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::saveImage + */ + public function testSaveImageFolderImage() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $stubFolderImage = $this->getMockBuilder('\Thelia\Model\FolderImage') + ->disableOriginalConstructor() + ->getMock(); + $stubFolderImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + + $fileManager = new FileManager($stubContainer); + + $event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_FOLDER, 24); + + $expected = 10; + $actual = $fileManager->saveImage($event, $stubFolderImage); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::saveImage + */ + public function testSaveImageContentImage() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $stubContentImage = $this->getMockBuilder('\Thelia\Model\ContentImage') + ->disableOriginalConstructor() + ->getMock(); + $stubContentImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + + $fileManager = new FileManager($stubContainer); + + $event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_CONTENT, 24); + + $expected = 10; + $actual = $fileManager->saveImage($event, $stubContentImage); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::saveImage + * @expectedException \Thelia\Exception\ImageException + */ + public function testSaveImageExceptionImageException() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + $fileManager = new FileManager($stubContainer); + + $stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage') + ->disableOriginalConstructor() + ->getMock(); + $stubProductImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(10)); + + $event = new ImageCreateOrUpdateEvent('bad', 24); + $modelImage = new ProductImage(); + + $fileManager->saveImage($event, $modelImage); + } + + /** + * @covers Thelia\Tools\FileManager::saveImage + * @expectedException \Thelia\Exception\ImageException + */ + public function testSaveImageExceptionImageException2() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + $fileManager = new FileManager($stubContainer); + + $stubProductImage = $this->getMockBuilder('\Thelia\Model\ProductImage') + ->disableOriginalConstructor() + ->getMock(); + $stubProductImage->expects($this->any()) + ->method('save') + ->will($this->returnValue(0)); + + $event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_PRODUCT, 24); + + $fileManager->saveImage($event, $stubProductImage); + } + + /** + * @covers Thelia\Tools\FileManager::sanitizeFileName + */ + public function testSanitizeFileName() + { + $stubContainer = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerInterface') + ->disableOriginalConstructor() + ->getMock(); + + $fileManager = new FileManager($stubContainer); + $badFileName = 'azeéràçè§^"$*+-_°)(&é<>@#ty'; + + $expected = 'azeyryZyy-_yty'; + $actual = $fileManager->sanitizeFileName($badFileName); + + $this->assertEquals($expected, $actual); + } + + /** + * @covers Thelia\Tools\FileManager::adminLogAppend + */ + public function testAdminLogAppend() + { + $this->markTestIncomplete( + 'This test has not been implemented yet.' + ); + } +} diff --git a/core/lib/Thelia/Tools/FileManager.php b/core/lib/Thelia/Tools/FileManager.php new file mode 100644 index 000000000..533dcb203 --- /dev/null +++ b/core/lib/Thelia/Tools/FileManager.php @@ -0,0 +1,222 @@ +. */ +/* */ +/**********************************************************************************/ +namespace Thelia\Tools; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\File\UploadedFile; +use Thelia\Core\Event\ImageCreateOrUpdateEvent; +use Thelia\Core\Event\ImageDeleteEvent; +use Thelia\Exception\ImageException; +use Thelia\Model\AdminLog; +use Thelia\Model\Base\CategoryImage; +use Thelia\Model\ContentImage; +use Thelia\Model\FolderImage; +use Thelia\Model\ProductImage; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/19/13 + * Time: 3:24 PM + * + * File Manager + * + * @package File + * @author Guillaume MOREL + * + */ +class FileManager +{ + /** @var ContainerInterface Service Container */ + protected $container = null; + + /** @var Translator Service Translator */ + protected $translator = null; + + /** + * Constructor + * + * @param ContainerInterface $container Service container + */ + public function __construct(ContainerInterface $container) + { + $this->container = $container; + $this->translator = $this->container->get('thelia.translator'); + } + + /** + * Copy UploadedFile into the server storage directory + * + * @param int $parentId Parent id + * @param string $imageType Image type + * @param FolderImage|ContentImage|CategoryImage|ProductImage $modelImage Image saved + * @param UploadedFile $uploadedFile Ready to be uploaded file + * @param array $newUploadedFiles UploadedFile array to update + * + * @throws \Thelia\Exception\ImageException + * @return array Updated UploadedFile array + */ + public function copyUploadedFile($parentId, $imageType, $modelImage, $uploadedFile, $newUploadedFiles) + { + if ($uploadedFile !== null) { + $directory = $modelImage->getUploadDir(); + $fileName = $this->sanitizeFileName( + $uploadedFile->getClientOriginalName() . "-" . $modelImage->getId() . "." . strtolower( + $uploadedFile->getClientOriginalExtension() + ) + ); + + $this->adminLogAppend( + $this->translator->trans( + 'Uploading picture %pictureName% to %directory% for parent_id %parentId% (%parentType%)', + array( + '%pictureName%' => $uploadedFile->getClientOriginalName(), + '%directory%' => $directory . '/' . $fileName, + '%parentId%' => $parentId, + '%parentType%' => $imageType + ), + 'image' + ) + ); + + $newUploadedFiles[] = array('file' => $uploadedFile->move($directory, $fileName)); + $modelImage->setFile($fileName); + + if (!$modelImage->save()) { + throw new ImageException( + sprintf( + 'Image %s (%s) failed to be saved (image file)', + $modelImage->getFile(), + $imageType + ) + ); + } + } + + return $newUploadedFiles; + } + + /** + * Save image into the database + * + * @param ImageCreateOrUpdateEvent $event Image event + * @param FolderImage|ContentImage|CategoryImage|ProductImage $modelImage Image to save + * + * @return int Nb lines modified + * @throws \Thelia\Exception\ImageException + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + */ + public function saveImage(ImageCreateOrUpdateEvent $event, $modelImage) + { + $nbModifiedLines = 0; + + if ($modelImage->getFile() !== null) { + switch ($event->getImageType()) { + case ImageCreateOrUpdateEvent::TYPE_PRODUCT: + /** @var ProductImage $modelImage */ + $modelImage->setProductId($event->getParentId()); + break; + case ImageCreateOrUpdateEvent::TYPE_CATEGORY: + /** @var CategoryImage $modelImage */ + $modelImage->setCategoryId($event->getParentId()); + break; + case ImageCreateOrUpdateEvent::TYPE_CONTENT: + /** @var ContentImage $modelImage */ + $modelImage->setContentId($event->getParentId()); + break; + case ImageCreateOrUpdateEvent::TYPE_FOLDER: + /** @var FolderImage $modelImage */ + $modelImage->setFolderId($event->getParentId()); + break; + default: + throw new ImageException( + sprintf( + 'Picture parent type is unknown (available types : %s)', + implode( + ',', + $event->getAvailableType() + ) + ) + ); + } + + $nbModifiedLines = $modelImage->save(); + if (!$nbModifiedLines) { + throw new ImageException( + sprintf( + 'Image %s failed to be saved (image content)', + $modelImage->getFile() + ) + ); + } + } + + return $nbModifiedLines; + } + + /** + * Sanitizes a filename replacing whitespace with dashes + * + * Removes special characters that are illegal in filenames on certain + * operating systems and special characters requiring special escaping + * to manipulate at the command line. + * + * @param string $string The filename to be sanitized + * + * @return string The sanitized filename + */ + public function sanitizeFileName($string) + { + $cleanName = strtr($string, 'ŠŽšžŸÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöøùúûüýÿ', 'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy'); + $cleanName = strtr($cleanName, array('Þ' => 'TH', 'þ' => 'th', 'Ð' => 'DH', 'ð' => 'dh', 'ß' => 'ss', 'Œ' => 'OE', 'œ' => 'oe', 'Æ' => 'AE', 'æ' => 'ae', 'µ' => 'u')); + + $cleanName = preg_replace(array('/\s/', '/\.[\.]+/', '/[^\w_\.\-]/'), array('_', '.', ''), $cleanName); + + return $cleanName; + } + + /** + * Helper to append a message to the admin log. + * + * @param string $message + */ + public function adminLogAppend($message) + { + AdminLog::append( + $message, + $this->container->get('request'), + $this->container->get('thelia.securityContext')->getAdminUser() + ); + } + + + /** + * Delete image from file storage and database + * + * @param CategoryImage|ProductImage|ContentImage|FolderImage $imageModel Image being deleted + */ + public function deleteImage($imageModel) + { + unlink($imageModel->getAbsolutePath()); + $imageModel->delete(); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Tools/I18n.php b/core/lib/Thelia/Tools/I18n.php index 1f3ff57dd..f043190c2 100644 --- a/core/lib/Thelia/Tools/I18n.php +++ b/core/lib/Thelia/Tools/I18n.php @@ -54,4 +54,5 @@ class I18n return \DateTime::createFromFormat($currentDateFormat, $date); } + } diff --git a/templates/admin/default/assets/js/image-upload.js b/templates/admin/default/assets/js/image-upload.js new file mode 100644 index 000000000..45e63ffbd --- /dev/null +++ b/templates/admin/default/assets/js/image-upload.js @@ -0,0 +1,67 @@ +// Manage picture upload +$(function($){ + + var pictureUploadManager = {}; + + // Set selected image as preview + pictureUploadManager.onChangePreviewPicture = function() { + $('#images input:file').on('change', function () { + var $this = $(this); + if ($this.prop("files") && $this.prop("files")[0]) { + var reader = new FileReader(); + + reader.onload = function (e) { + $this.parent() + .find('img.preview') + .attr('src', e.target.result) + .width(150) + .height(200); + } + + reader.readAsDataURL($this.prop("files")[0]); + } + }); + }; + pictureUploadManager.onChangePreviewPicture(); + + // Remove image on click + pictureUploadManager.onClickDeleteImage = function() { + $('.image-manager .image-delete-btn').on('click', function (e) { + console.log('deletingImage'); + e.preventDefault(); + var $this = $(this); + $this.parent().append('
'); + var $url = $this.attr("href"); + var errorMessage = $this.attr("data-error-message"); + $.ajax({ + type: "POST", + url: $url, + statusCode: { + 404: function() { + $(".image-manager .message").html( + errorMessage + ); + } + } + }).done(function(data) { + $this.parent().remove(); + $(".image-manager .message").html( + data + ); + }); + }); + }; + pictureUploadManager.onClickDeleteImage(); + + // Remove image on click + pictureUploadManager.clonePictureInputs = function() { + var $inputs = $(".image-manager .picture-input"); + if ($inputs.size == 1) { + console.log('1'); + $(".image-manager .picture-input").last().show(); + } else { + console.log('+d1'); + $(".image-manager .picture-input").last().clone().appendTo(".image-manager .pictures-input"); + } + } +}); \ No newline at end of file diff --git a/templates/admin/default/category-edit.html b/templates/admin/default/category-edit.html index 6d1c4a9c2..8d1fcfd45 100755 --- a/templates/admin/default/category-edit.html +++ b/templates/admin/default/category-edit.html @@ -246,31 +246,7 @@
- image - {form name="thelia.admin.category.picture.creation"} - - {form_hidden_fields form=$form} - - - {form_field form=$form field='title'} -
- - - {if $error}{$message}{/if} -
- {/form_field} - - {form_field form=$form field='file'} -
- - - {if $error}{$message}{/if} -
- {/form_field} - - - - {/form} + {include file='includes/image-upload-form.html' formName="thelia.admin.category.image.creation" formSuccessUrl={url path="/admin/categories/update?category_id=$category_id"} imageType='category' parentId=$category_id}
@@ -311,6 +287,9 @@ {/block} {block name="javascript-initialization"} +{javascripts file='assets/js/image-upload.js'} + +{/javascripts} diff --git a/templates/admin/default/ajax/template-feature-list.html b/templates/admin/default/ajax/template-feature-list.html index 9505c718a..c864047ba 100644 --- a/templates/admin/default/ajax/template-feature-list.html +++ b/templates/admin/default/ajax/template-feature-list.html @@ -33,6 +33,8 @@ {intl l='Feature title'} + {intl l='Position'} + {module_include location='template_features_table_header'} {intl l="Actions"} @@ -48,6 +50,17 @@ {$TITLE} + + {admin_position_block + permission="admin.templates.edit" + path={url path="/admin/template/update-feature-position" template_id=$template_id} + url_parameter="feature_id" + in_place_edit_class="featurePositionChange" + position=$POSITION + id=$ID + } + + {module_include location='template_features_table_row'} @@ -64,7 +77,7 @@ {elseloop rel="assigned_features"} - +
{intl l="This template contains no features"}
@@ -100,5 +113,26 @@ $('a.delete-feature').click(function(ev) { $('#feature_delete_id').val($(this).data('id')); }); + + {* Inline editing of object position using bootstrap-editable *} + + $('.featurePositionChange').editable({ + type : 'text', + title : '{intl l="Enter new category position"}', + mode : 'popup', + inputclass : 'input-mini', + placement : 'left', + success : function(response, newValue) { + // The URL template + var url = "{url noamp='1' path='/admin/template/update-feature-position' template_id=$template_id feature_id='__ID__' position='__POS__'}"; + + // Perform subtitutions + url = url.replace('__ID__', $(this).data('id')).replace('__POS__', newValue); + + // Reload the page + location.href = url; + } + }); + }); diff --git a/templates/admin/default/attribute-edit.html b/templates/admin/default/attribute-edit.html index 676a99baa..d15703910 100644 --- a/templates/admin/default/attribute-edit.html +++ b/templates/admin/default/attribute-edit.html @@ -303,7 +303,7 @@ placement : 'left', success : function(response, newValue) { // The URL template - var url = "{url path='/admin/configuration/attributes-av/update-position' attributeav_id='__ID__' position='__POS__' attribute_id=$attribute_id}"; + var url = "{url noamp='1' 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); diff --git a/templates/admin/default/attributes.html b/templates/admin/default/attributes.html index c207d02fa..dd2572a2b 100644 --- a/templates/admin/default/attributes.html +++ b/templates/admin/default/attributes.html @@ -312,7 +312,7 @@ placement : 'left', success : function(response, newValue) { // The URL template - var url = "{url path='/admin/configuration/attributes/update-position' attribute_id='__ID__' position='__POS__'}"; + var url = "{url noamp='1' path='/admin/configuration/attributes/update-position' attribute_id='__ID__' position='__POS__'}"; // Perform subtitutions url = url.replace('__ID__', $(this).data('id')) diff --git a/templates/admin/default/categories.html b/templates/admin/default/categories.html index 990cafd56..68e84014f 100755 --- a/templates/admin/default/categories.html +++ b/templates/admin/default/categories.html @@ -604,7 +604,7 @@ placement : 'left', success : function(response, newValue) { // The URL template - var url = "{url path='/admin/categories/update-position' category_id='__ID__' position='__POS__'}"; + var url = "{url noamp='1' path='/admin/categories/update-position' category_id='__ID__' position='__POS__'}"; // Perform subtitutions url = url.replace('__ID__', $(this).data('id')) @@ -623,7 +623,7 @@ placement : 'left', success : function(response, newValue) { // The URL template - var url = "{url path='/admin/products/update-position' product_id='__ID__' position='__POS__'}"; + var url = "{url noamp='1' path='/admin/products/update-position' product_id='__ID__' position='__POS__'}"; // Perform subtitutions url = url.replace('__ID__', $(this).data('id')) diff --git a/templates/admin/default/currencies.html b/templates/admin/default/currencies.html index 11b52cd24..e53d86277 100644 --- a/templates/admin/default/currencies.html +++ b/templates/admin/default/currencies.html @@ -331,7 +331,7 @@ placement : 'left', success : function(response, newValue) { // The URL template - var url = "{url path='/admin/configuration/currencies/update-position' currency_id='__ID__' position='__POS__'}"; + var url = "{url noamp='1' path='/admin/configuration/currencies/update-position' currency_id='__ID__' position='__POS__'}"; // Perform subtitutions url = url.replace('__ID__', $(this).data('id')) diff --git a/templates/admin/default/feature-edit.html b/templates/admin/default/feature-edit.html index 41a6276b9..25c2d6017 100644 --- a/templates/admin/default/feature-edit.html +++ b/templates/admin/default/feature-edit.html @@ -303,7 +303,7 @@ placement : 'left', success : function(response, newValue) { // The URL template - var url = "{url path='/admin/configuration/features-av/update-position' featureav_id='__ID__' position='__POS__' feature_id=$feature_id}"; + var url = "{url noamp='1' path='/admin/configuration/features-av/update-position' featureav_id='__ID__' position='__POS__' feature_id=$feature_id}"; // Perform subtitutions url = url.replace('__ID__', $(this).data('id')).replace('__POS__', newValue); diff --git a/templates/admin/default/features.html b/templates/admin/default/features.html index 683374aa8..f58a19bc2 100644 --- a/templates/admin/default/features.html +++ b/templates/admin/default/features.html @@ -312,7 +312,7 @@ placement : 'left', success : function(response, newValue) { // The URL template - var url = "{url path='/admin/configuration/features/update-position' feature_id='__ID__' position='__POS__'}"; + var url = "{url noamp='1' path='/admin/configuration/features/update-position' feature_id='__ID__' position='__POS__'}"; // Perform subtitutions url = url.replace('__ID__', $(this).data('id')) diff --git a/templates/admin/default/folders.html b/templates/admin/default/folders.html index 90646c9bc..fcfc32f15 100644 --- a/templates/admin/default/folders.html +++ b/templates/admin/default/folders.html @@ -7,8 +7,8 @@ {block name="main-content"}
-
- +
+ {* include file="includes/folder-breadcrumb.html" *} {module_include location='folders_top'} @@ -213,7 +213,7 @@ label="{intl l='ID'}" } -   +   {admin_sortable_header @@ -416,7 +416,7 @@ {form_field form=$form field='default_folder'} - {/form_field} + {/form_field} {form_field form=$form field='title'}
@@ -580,7 +580,7 @@ placement : 'left', success : function(response, newValue) { // The URL template - var url = "{url path='/admin/folders/update-position' folder_id='__ID__' position='__POS__'}"; + var url = "{url noamp='1' path='/admin/folders/update-position' folder_id='__ID__' position='__POS__'}"; // Perform subtitutions url = url.replace('__ID__', $(this).data('id')) @@ -599,7 +599,7 @@ placement : 'left', success : function(response, newValue) { // The URL template - var url = "{url path='/admin/contents/update-position' content_id='__ID__' position='__POS__'}"; + var url = "{url noamp='1' path='/admin/contents/update-position' content_id='__ID__' position='__POS__'}"; // Perform subtitutions url = url.replace('__ID__', $(this).data('id')) diff --git a/templates/admin/default/product-edit.html b/templates/admin/default/product-edit.html index 4464e0071..f1384148b 100644 --- a/templates/admin/default/product-edit.html +++ b/templates/admin/default/product-edit.html @@ -221,7 +221,7 @@ $(function() { placement : 'left', success : function(response, newValue) { // The URL template - var url = "{url path='admin/product/update-accessory-position/' accessory_id='__ID__' product_id=$product_id position='__POS__'}"; + var url = "{url noamp='1' path='admin/product/update-accessory-position/' accessory_id='__ID__' product_id=$product_id position='__POS__'}"; // Perform subtitutions url = url.replace('__ID__', $(this).data('id')).replace('__POS__', newValue); diff --git a/templates/admin/default/template-edit.html b/templates/admin/default/template-edit.html index 7b9ddd4aa..8cc6a0e7e 100644 --- a/templates/admin/default/template-edit.html +++ b/templates/admin/default/template-edit.html @@ -106,10 +106,14 @@ {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/templates.html b/templates/admin/default/templates.html index f7e912e9c..839f8b5ed 100644 --- a/templates/admin/default/templates.html +++ b/templates/admin/default/templates.html @@ -25,7 +25,7 @@ {if ! empty($general_error) }
{$general_error}
{/if} - +
+ @@ -303,7 +303,7 @@ } - + {/loop} - - {intl l='Select a category to get its products'} - - -
-
- - - - -
- - {intl l='Select a product and click (+) to add it as an accessory'} -
- -
-
- {intl l="No available product in this category"} -
-
- - {/ifloop} - - {elseloop rel="categories"} -
{intl l="No categories found"}
- {/elseloop} - - - - -
-
@@ -194,10 +194,6 @@ {block name="javascript-initialization"} - {javascripts file='assets/js/bootstrap-editable/bootstrap-editable.js'} - - {/javascripts} - diff --git a/templates/admin/default/includes/product-general-tab.html b/templates/admin/default/ajax/product-general-tab.html similarity index 91% rename from templates/admin/default/includes/product-general-tab.html rename to templates/admin/default/ajax/product-general-tab.html index 3eb2d6fe0..8f6cdc20a 100644 --- a/templates/admin/default/includes/product-general-tab.html +++ b/templates/admin/default/ajax/product-general-tab.html @@ -1,9 +1,16 @@ +{loop name="product_edit" type="product" visible="*" id=$product_id backend_context="1" lang=$edit_language_id}
{form name="thelia.admin.product.modification"}
- {include file="includes/inner-form-toolbar.html" close_url="{url path='/admin/products' product_id=$product_id}"} + {include + file = "includes/inner-form-toolbar.html" + hide_submit_buttons = false + + page_url = "{url path='/admin/products/update' product_id=$ID}" + close_url = "{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}" + } {* Be sure to get the product ID, even if the form could not be validated *} @@ -104,3 +111,4 @@
{/form}
+{/loop} \ No newline at end of file diff --git a/templates/admin/default/includes/product-content-tab.html b/templates/admin/default/ajax/product-related-tab.html similarity index 66% rename from templates/admin/default/includes/product-content-tab.html rename to templates/admin/default/ajax/product-related-tab.html index e17517930..8d705e9ae 100644 --- a/templates/admin/default/includes/product-content-tab.html +++ b/templates/admin/default/ajax/product-related-tab.html @@ -1,22 +1,25 @@ +{loop name="product_edit" type="product" visible="*" id=$product_id backend_context="1" lang=$edit_language_id}
{include - file="includes/inner-form-toolbar.html" - hide_submit_buttons=true - close_url="{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}" + file = "includes/inner-form-toolbar.html" + hide_submit_buttons = true + + page_url = "{url path='/admin/products/update' product_id=$ID}" + close_url = "{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}" } {* -- Begin related content management -- *}
-
{admin_position_block permission="admin.products.edit" - path={url path='/admin/products/update-accessory-position' product_id=$ID} + path={url path='/admin/product/update-accessory-position' product_id=$product_id current_tab="related"} url_parameter="accessory_id" in_place_edit_class="accessoryPositionChange" position=$POSITION @@ -237,7 +240,7 @@ - + {/capture} {include @@ -247,7 +250,7 @@ dialog_title = {intl l="Remove related content"} dialog_message = {intl l="Do you really want to remove this related content from the product ?"} - form_action = {url path='/admin/products/related-content/delete'} + form_action = {url path='/admin/products/content/delete'} form_content = {$smarty.capture.delete_content_dialog nofilter} } @@ -258,7 +261,7 @@ - + {/capture} {include @@ -270,4 +273,136 @@ form_action = {url path='/admin/products/accessory/delete'} form_content = {$smarty.capture.delete_accessory_dialog nofilter} -} \ No newline at end of file +} + + +{/loop} \ 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 822130a5c..7de53f5aa 100644 --- a/templates/admin/default/assets/less/thelia/thelia.less +++ b/templates/admin/default/assets/less/thelia/thelia.less @@ -226,6 +226,14 @@ } } +.tab-content { + // Center loading indicator + .loading { + margin: 8em auto; + text-align: center; + } +} + // The overall form container .form-container { @@ -275,5 +283,8 @@ .loading{ background: url("@{imgDir}/ajax-loader.gif") no-repeat; height: 30px; - width: 30px; + display: inline-block; + line-height: 30px; + padding-left: 40px; + width: auto; } \ No newline at end of file diff --git a/templates/admin/default/categories.html b/templates/admin/default/categories.html index 68e84014f..2c53d71dc 100755 --- a/templates/admin/default/categories.html +++ b/templates/admin/default/categories.html @@ -256,7 +256,7 @@ } -  {intl l="Actions"}
+
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.product.edit"} diff --git a/templates/admin/default/includes/inner-form-toolbar.html b/templates/admin/default/includes/inner-form-toolbar.html index 39da9fce7..f0ddeb924 100755 --- a/templates/admin/default/includes/inner-form-toolbar.html +++ b/templates/admin/default/includes/inner-form-toolbar.html @@ -1,18 +1,21 @@ +{* +A toolbar displayed in forms, to display language change flags, submit and close buttons. + +Parameters: + + - hide_submit_buttons: true / false. If true, only the close button will be deplayed. + - page_url: the current page URL. Dafault id $current_url. Used to switchedition anguage. + - close_url: no default. URL displayed when close button is clicked. If empty, the close button is not displayed. +*} +
{* Display the top form toolbar, with edition flags, and save buttons *} - {* When creating a new object, only default language is displayed *} - {if $action == 'create'} - {$default_only = 1} - {else} - {$default_only = 0} - {/if} -
+
\ No newline at end of file diff --git a/templates/admin/default/product-attributes-edit.html b/templates/admin/default/product-attributes-edit.html deleted file mode 100644 index e69de29bb..000000000 diff --git a/templates/admin/default/product-edit.html b/templates/admin/default/product-edit.html index f1384148b..5c0f89c79 100644 --- a/templates/admin/default/product-edit.html +++ b/templates/admin/default/product-edit.html @@ -6,6 +6,7 @@ {block name="main-content"}
+
{include file="includes/catalog-breadcrumb.html" editing_category="false" editing_product="true"} @@ -40,41 +41,56 @@
-
- - {include file="includes/product-general-tab.html"} - +
+
{intl l="Please wait, loading"}
-
- - {include file="includes/product-attributes-tab.html"} - +
+
{intl l="Please wait, loading"}
-
- - {include file="includes/product-content-tab.html"} - + -
+
+
{intl l="Please wait, loading"}
-
+
+
{intl l="Please wait, loading"}
-
+
+
{intl l="Please wait, loading"}
@@ -116,137 +132,14 @@ {/block} \ No newline at end of file From b91a11536b03cf1a01293981f41dcd658e82899a Mon Sep 17 00:00:00 2001 From: gmorel Date: Sun, 22 Sep 2013 20:50:42 +0200 Subject: [PATCH 10/43] Working : Image management set on Category --- composer.json | 3 +- composer.lock | 67 +- core/lib/Thelia/Action/Image.php | 111 +- core/lib/Thelia/Config/Resources/config.xml | 2 +- .../Thelia/Config/Resources/routing/admin.xml | 17 +- .../Controller/Admin/FileController.php | 306 +-- .../Core/Event/ImageCreateOrUpdateEvent.php | 159 +- .../Thelia/Core/Event/ImageDeleteEvent.php | 32 +- .../Core/Event/ImagesCreateOrUpdateEvent.php | 184 ++ core/lib/Thelia/Core/Event/TheliaEvents.php | 5 + ...Form.php => CategoryImageModification.php} | 28 +- ...yType.php => ContentImageModification.php} | 42 +- ...geType.php => FolderImageModification.php} | 53 +- .../Thelia/Form/Image/ImageModification.php | 183 ++ .../Thelia/Form/ProductImageModification.php | 53 + core/lib/Thelia/Model/CategoryImage.php | 35 +- core/lib/Thelia/Model/ContentImage.php | 14 + core/lib/Thelia/Model/FolderImage.php | 14 + core/lib/Thelia/Model/ProductImage.php | 14 + .../Thelia/Tests/Tools/FileManagerTest.php | 18 +- core/lib/Thelia/Tools/FileManager.php | 275 ++- local/modules/Cheque/images/cheque.png | Bin local/modules/FakeCB/images/mastercard.png | Bin local/modules/FakeCB/images/visa.png | Bin templates/admin/default/assets/js/dropzone.js | 1758 +++++++++++++++++ .../admin/default/assets/js/image-upload.js | 65 +- templates/admin/default/category-edit.html | 13 +- templates/admin/default/image-edit.html | 120 ++ .../default/includes/image-upload-form.html | 536 ++++- .../includes/image-upload-list-ajax.html | 23 + web/test_to_remove/admin-stats.json | 0 31 files changed, 3620 insertions(+), 510 deletions(-) create mode 100755 core/lib/Thelia/Core/Event/ImagesCreateOrUpdateEvent.php rename core/lib/Thelia/Form/{CategoryImageCreationForm.php => CategoryImageModification.php} (75%) rename core/lib/Thelia/Form/{Type/ImageCategoryType.php => ContentImageModification.php} (66%) rename core/lib/Thelia/Form/{Type/ImageType.php => FolderImageModification.php} (58%) create mode 100644 core/lib/Thelia/Form/Image/ImageModification.php create mode 100644 core/lib/Thelia/Form/ProductImageModification.php mode change 100644 => 100755 local/modules/Cheque/images/cheque.png mode change 100644 => 100755 local/modules/FakeCB/images/mastercard.png mode change 100644 => 100755 local/modules/FakeCB/images/visa.png create mode 100644 templates/admin/default/assets/js/dropzone.js create mode 100644 templates/admin/default/image-edit.html create mode 100644 templates/admin/default/includes/image-upload-list-ajax.html mode change 100644 => 100755 web/test_to_remove/admin-stats.json diff --git a/composer.json b/composer.json index 4a3798384..afef9e30b 100755 --- a/composer.json +++ b/composer.json @@ -37,7 +37,8 @@ "imagine/imagine": "dev-master", "symfony/icu": "1.0", - "swiftmailer/swiftmailer": "5.0.*" + "swiftmailer/swiftmailer": "5.0.*", + "symfony/serializer": "2.3.*" }, "require-dev" : { "phpunit/phpunit": "3.7.*", diff --git a/composer.lock b/composer.lock index b0310c075..f90373a84 100755 --- a/composer.lock +++ b/composer.lock @@ -3,7 +3,7 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "a40be01c82e68ba0c446dc204d2667da", + "hash": "097481390dc87b3482d895b3b6a65479", "packages": [ { "name": "imagine/imagine", @@ -1456,6 +1456,53 @@ "homepage": "http://symfony.com", "time": "2013-08-23 14:06:02" }, + { + "name": "symfony/serializer", + "version": "v2.3.4", + "target-dir": "Symfony/Component/Serializer", + "source": { + "type": "git", + "url": "https://github.com/symfony/Serializer.git", + "reference": "457ba76395955926a67ea692957b0872dead5278" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Serializer/zipball/457ba76395955926a67ea692957b0872dead5278", + "reference": "457ba76395955926a67ea692957b0872dead5278", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Serializer\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Serializer Component", + "homepage": "http://symfony.com", + "time": "2013-07-21 12:12:18" + }, { "name": "symfony/translation", "version": "v2.2.6", @@ -1722,12 +1769,12 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "1.2.12" + "reference": "0e9958c459d675fb497d8dc5001c91d335734e48" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1.2.12", - "reference": "1.2.12", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/0e9958c459d675fb497d8dc5001c91d335734e48", + "reference": "0e9958c459d675fb497d8dc5001c91d335734e48", "shasum": "" }, "require": { @@ -1916,12 +1963,12 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "1.2.0" + "reference": "31babf400e5b5868573bf49a000a3519d3978233" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1.2.0", - "reference": "1.2.0", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/31babf400e5b5868573bf49a000a3519d3978233", + "reference": "31babf400e5b5868573bf49a000a3519d3978233", "shasum": "" }, "require": { @@ -1966,12 +2013,12 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "3.7.24" + "reference": "af7b77ccb5c64458bdfca95665d29558d1df7d08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.24", - "reference": "3.7.24", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/af7b77ccb5c64458bdfca95665d29558d1df7d08", + "reference": "af7b77ccb5c64458bdfca95665d29558d1df7d08", "shasum": "" }, "require": { diff --git a/core/lib/Thelia/Action/Image.php b/core/lib/Thelia/Action/Image.php index 41ce957d4..989c9c516 100755 --- a/core/lib/Thelia/Action/Image.php +++ b/core/lib/Thelia/Action/Image.php @@ -28,6 +28,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\File\UploadedFile; use Thelia\Core\Event\ImageCreateOrUpdateEvent; +use Thelia\Core\Event\ImagesCreateOrUpdateEvent; use Thelia\Core\Event\ImageDeleteEvent; use Thelia\Core\Event\ImageEvent; use Thelia\Model\CategoryImage; @@ -252,21 +253,20 @@ class Image extends BaseCachedFile implements EventSubscriberInterface } /** - * Take care of saving images in the database and file storage + * Take care of saving image in the database and file storage * * @param ImageCreateOrUpdateEvent $event Image event * * @throws \Thelia\Exception\ImageException * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action */ - public function saveImages(ImageCreateOrUpdateEvent $event) + public function saveImage(ImageCreateOrUpdateEvent $event) { - $fileManager = new FileManager($this->container); - $this->adminLogAppend( $this->container->get('thelia.translator')->trans( - 'Saving images for parent id %parentId% (%parentType%)', + 'Saving images for %parentName% parent id %parentId% (%parentType%)', array( + '%parentName%' => $event->getParentName(), '%parentId%' => $event->getParentId(), '%parentType%' => $event->getImageType() ), @@ -274,37 +274,75 @@ class Image extends BaseCachedFile implements EventSubscriberInterface ) ); - $newUploadedFiles = array(); - $uploadedFiles = $event->getUploadedFiles(); + $fileManager = new FileManager($this->container); + $model = $event->getModelImage(); - foreach ($event->getModelImages() as $i => $modelImage) { - // Save image to database in order to get image id - $fileManager->saveImage($event, $modelImage); + $nbModifiedLines = $model->save(); + $event->setModelImage($model); - if (isset($uploadedFiles) && isset($uploadedFiles[$i])) { - /** @var UploadedFile $uploadedFile */ - $uploadedFile = $uploadedFiles[$i]['file']; - - // Copy uploaded file into the storage directory - $newUploadedFiles = $fileManager->copyUploadedFile($event->getParentId(), $event->getImageType(), $modelImage, $uploadedFile, $newUploadedFiles); - } else { - throw new ImageException( - sprintf( - 'File with name %s not found on the server', - $modelImage->getFile() - ) - ); - } - $event->setUploadedFiles($newUploadedFiles); + if (!$nbModifiedLines) { + throw new ImageException( + sprintf( + 'Image "%s" with parent id %s (%s) failed to be saved', + $event->getParentName(), + $event->getParentId(), + $event->getImageType() + ) + ); } + + $newUploadedFile = $fileManager->copyUploadedFile($event->getParentId(), $event->getImageType(), $event->getModelImage(), $event->getUploadedFile()); + $event->setUploadedFile($newUploadedFile); + } + + /** + * Take care of updating image in the database and file storage + * + * @param ImageCreateOrUpdateEvent $event Image event + * + * @throws \Thelia\Exception\ImageException + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + */ + public function updateImage(ImageCreateOrUpdateEvent $event) + { + $this->adminLogAppend( + $this->container->get('thelia.translator')->trans( + 'Updating images for %parentName% parent id %parentId% (%parentType%)', + array( + '%parentName%' => $event->getParentName(), + '%parentId%' => $event->getParentId(), + '%parentType%' => $event->getImageType() + ), + 'image' + ) + ); + + $fileManager = new FileManager($this->container); + // Copy and save file + if ($event->getUploadedFile()) { + // Remove old picture file from file storage + $url = $fileManager->getUploadDir($event->getImageType()) . '/' . $event->getOldModelImage()->getFile(); + unlink(str_replace('..', '', $url)); + + $newUploadedFile = $fileManager->copyUploadedFile( + $event->getModelImage()->getParentId(), + $event->getImageType(), + $event->getModelImage(), $event->getUploadedFile()); + $event->setUploadedFile($newUploadedFile); + } + + // Update image modifications + $event->getModelImage()->save(); + $event->setModelImage($event->getModelImage()); + } /** * Take care of deleting image in the database and file storage * - * @param ImageCreateOrUpdateEvent $event Image event + * @param ImageDeleteEvent $event Image event * - * @throws \Thelia\Exception\ImageException + * @throws \Exception * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action */ public function deleteImage(ImageDeleteEvent $event) @@ -312,7 +350,7 @@ class Image extends BaseCachedFile implements EventSubscriberInterface $fileManager = new FileManager($this->container); try { - $fileManager->deleteImage($event->getImageToDelete()); + $fileManager->deleteImage($event->getImageToDelete(), $event->getImageType()); $this->adminLogAppend( $this->container->get('thelia.translator')->trans( @@ -336,22 +374,10 @@ class Image extends BaseCachedFile implements EventSubscriberInterface 'image' ) ); + throw $e; } } - /** - * The absolute directory path where uploaded - * documents should be saved - * - * @param $modelImage Image model - * - * @return string - */ - public function getUploadRootDir($modelImage) - { - return __DIR__.'/../../../../' . $modelImage->getUploadDir(); - } - /** * Process image resizing, with borders or cropping. If $dest_width and $dest_height * are both null, no resize is performed. @@ -474,8 +500,9 @@ class Image extends BaseCachedFile implements EventSubscriberInterface return array( TheliaEvents::IMAGE_PROCESS => array("processImage", 128), TheliaEvents::IMAGE_CLEAR_CACHE => array("clearCache", 128), - TheliaEvents::IMAGE_SAVE => array("saveImages", 128), TheliaEvents::IMAGE_DELETE => array("deleteImage", 128), + TheliaEvents::IMAGE_SAVE => array("saveImage", 128), + TheliaEvents::IMAGE_UPDATE => array("updateImage", 128), ); } } diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 2c755550d..8832cdd2d 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -58,7 +58,7 @@ - + diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 8b91500d1..c9e1be4d4 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -39,11 +39,24 @@ - - Thelia\Controller\Admin\FileController::saveImagesAction + + Thelia\Controller\Admin\FileController::saveImageAjaxAction .* \d+ + + Thelia\Controller\Admin\FileController::getImageListAjaxAction + .* + \d+ + + + Thelia\Controller\Admin\FileController::viewImageAction + \d+ + + + Thelia\Controller\Admin\FileController::updateImageAction + \d+ + Thelia\Controller\Admin\FileController::deleteImagesAction .* diff --git a/core/lib/Thelia/Controller/Admin/FileController.php b/core/lib/Thelia/Controller/Admin/FileController.php index 4be913bcb..2592db192 100755 --- a/core/lib/Thelia/Controller/Admin/FileController.php +++ b/core/lib/Thelia/Controller/Admin/FileController.php @@ -23,20 +23,20 @@ namespace Thelia\Controller\Admin; +use Propel\Runtime\Exception\PropelException; +use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Router; use Thelia\Core\Event\ImageCreateOrUpdateEvent; +use Thelia\Core\Event\ImagesCreateOrUpdateEvent; use Thelia\Core\Event\ImageDeleteEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Translation\Translator; -use Thelia\Form\CategoryImageCreationForm; use Thelia\Form\Exception\FormValidationException; use Thelia\Log\Tlog; -use Thelia\Model\CategoryImageQuery; -use Thelia\Model\ContentImageQuery; -use Thelia\Model\FolderImageQuery; -use Thelia\Model\ProductImageQuery; +use Thelia\Tools\FileManager; +use Thelia\Tools\Rest\ResponseRest; /** * Created by JetBrains PhpStorm. @@ -57,13 +57,14 @@ class FileController extends BaseAdminController * * @param int $parentId Parent id owning files being saved * @param string $parentType Parent Type owning files being saved - * @param string $successUrl Success URL to be redirected to * * @return Response */ - public function saveFilesAction($parentId, $parentType, $successUrl) + public function saveFilesAction($parentId, $parentType) { + + } /** @@ -74,77 +75,165 @@ class FileController extends BaseAdminController * * @return Response */ - public function saveImagesAction($parentId, $parentType) + public function saveImageAjaxAction($parentId, $parentType) { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.image.save")) { - return $response; - } - - $message = $this->getTranslator() - ->trans( - 'Images saved successfully', - array(), - 'image' - ); + $this->checkAuth('ADMIN', 'admin.image.save'); + $this->checkXmlHttpRequest(); if ($this->isParentTypeValid($parentType)) { if ($this->getRequest()->isMethod('POST')) { - // Create the form from the request - $creationForm = $this->getImageForm($parentType, $this->getRequest()); - try { - // Check the form against constraints violations - $form = $this->validateForm($creationForm, 'POST'); + /** @var UploadedFile $fileBeingUploaded */ + $fileBeingUploaded = $this->getRequest()->files->get('file'); - // Get the form field values - $data = $form->getData(); + $fileManager = new FileManager($this->container); + $parentModel = $fileManager->getParentImageModel($parentType, $parentId); + $imageModel = $fileManager->getImageModel($parentType); - // Feed event - $imageCreateOrUpdateEvent = new ImageCreateOrUpdateEvent( - $parentType, - $parentId - ); - if (isset($data) && isset($data['pictures'])) { - $imageCreateOrUpdateEvent->setModelImages($data['pictures']); - $imageCreateOrUpdateEvent->setUploadedFiles($this->getRequest()->files->get($creationForm->getName())['pictures']); - } - - // Dispatch Event to the Action - $this->dispatch( - TheliaEvents::IMAGE_SAVE, - $imageCreateOrUpdateEvent - ); - - } catch (FormValidationException $e) { - // Invalid data entered - $message = 'Please check your input:'; - $this->logError($parentType, 'image saving', $message, $e); - - } catch (\Exception $e) { - // Any other error - $message = 'Sorry, an error occurred:'; - $this->logError($parentType, 'image saving', $message, $e); + if ($parentModel === null || $imageModel === null || $fileBeingUploaded === null) { + return new Response('', 404); } - if ($message !== false) { - // Mark the form as with error - $creationForm->setErrorMessage($message); + $defaultTitle = $parentModel->getTitle(); + $imageModel->setParentId($parentId); + $imageModel->setTitle($defaultTitle); - // Send the form and the error to the parser - $this->getParserContext() - ->addForm($creationForm) - ->setGeneralError($message); + $imageCreateOrUpdateEvent = new ImageCreateOrUpdateEvent( + $parentType, + $parentId + ); + $imageCreateOrUpdateEvent->setModelImage($imageModel); + $imageCreateOrUpdateEvent->setUploadedFile($fileBeingUploaded); + $imageCreateOrUpdateEvent->setParentName($parentModel->getTitle()); - // Set flash message to be displayed - $flashMessage = $this->getSession()->get('flashMessage'); - $flashMessage['imageMessage'] = $message; - $this->getSession()->set('flashMessage', $flashMessage); - } + + // Dispatch Event to the Action + $this->dispatch( + TheliaEvents::IMAGE_SAVE, + $imageCreateOrUpdateEvent + ); + + + return new ResponseRest(array('status' => true, 'message' => '')); } } - $this->redirectSuccess($creationForm); + return new Response('', 404); + } + + /** + * Manage how a image list will be displayed in AJAX + * + * @param int $parentId Parent id owning images being saved + * @param string $parentType Parent Type owning images being saved + * + * @return Response + */ + public function getImageListAjaxAction($parentId, $parentType) + { + $this->checkAuth('ADMIN', 'admin.image.save'); + $this->checkXmlHttpRequest(); + $args = array('imageType' => $parentType, 'parentId' => $parentId); + + return $this->render('includes/image-upload-list-ajax', $args); + } + + /** + * Manage how an image is viewed + * + * @param int $imageId Parent id owning images being saved + * @param string $parentType Parent Type owning images being saved + * + * @return Response + */ + public function viewImageAction($imageId, $parentType) + { + if (null !== $response = $this->checkAuth('admin.image.view')) return $response; + try { + $fileManager = new FileManager($this->container); + $image = $fileManager->getImageModelQuery($parentType)->findPk($imageId); + $redirectUrl = $fileManager->getRedirectionUrl($parentType, $image->getParentId()); + + return $this->render('image-edit', array( + 'imageId' => $imageId, + 'imageType' => $parentType, + 'redirectUrl' => $redirectUrl + )); + } catch (Exception $e) { + $this->pageNotFound(); + } + } + + /** + * Manage how an image is updated + * + * @param int $imageId Parent id owning images being saved + * @param string $parentType Parent Type owning images being saved + * + * @return Response + */ + public function updateImageAction($imageId, $parentType) + { + if (null !== $response = $this->checkAuth('admin.image.update')) return $response; + + $message = false; + + $fileManager = new FileManager($this->container); + $imageModification = $fileManager->getImageForm($parentType, $this->getRequest()); + + try { + $image = $fileManager->getImageModelQuery($parentType)->findPk($imageId); + $oldImage = clone $image; + if(null === $image) { + throw new \InvalidArgumentException(sprintf('%d image id does not exists', $imageId)); + } + + $form = $this->validateForm($imageModification); + + $event = $this->createEventInstance($parentType, $image, $form->getData()); + $event->setOldModelImage($oldImage); + + $files = $this->getRequest()->files; + $fileForm = $files->get($imageModification->getName()); + if(isset($fileForm['file'])) { + $event->setUploadedFile($fileForm['file']); + } + + $this->dispatch(TheliaEvents::IMAGE_UPDATE, $event); + + $imageUpdated = $event->getModelImage(); + + $this->adminLogAppend(sprintf('Image with Ref %s (ID %d) modified', $imageUpdated->getTitle() , $imageUpdated->getId())); + + if($this->getRequest()->get('save_mode') == 'close') { + $this->redirectToRoute('admin.images'); + } else { + $this->redirectSuccess($imageModification); + } + + } 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 occurred: %s', $e->getMessage().' '.$e->getFile()); + } + + if ($message !== false) { + Tlog::getInstance()->error(sprintf('Error during image editing : %s.', $message)); + + $imageModification->setErrorMessage($message); + + $this->getParserContext() + ->addForm($imageModification) + ->setGeneralError($message) + ; + } + + return $this->render('image-edit', array( + 'imageId' => $imageId, + 'imageType' => $parentType + )); } /** @@ -160,14 +249,18 @@ class FileController extends BaseAdminController $this->checkAuth('ADMIN', 'admin.image.delete'); $this->checkXmlHttpRequest(); - $model = $this->getImageModel($parentType, $imageId); + $fileManager = new FileManager($this->container); + $imageModelQuery = $fileManager->getImageModelQuery($parentType); + $model = $imageModelQuery->findPk($imageId); + if ($model == null) { return $this->pageNotFound(); } // Feed event $imageDeleteEvent = new ImageDeleteEvent( - $model + $model, + $parentType ); // Dispatch Event to the Action @@ -218,73 +311,42 @@ class FileController extends BaseAdminController */ public function isParentTypeValid($parentType) { - return (in_array($parentType, ImageCreateOrUpdateEvent::getAvailableType())); + return (in_array($parentType, ImagesCreateOrUpdateEvent::getAvailableType())); } /** - * Get Image form + * Create Event instance * - * @param string $parentType Parent type - * @param Request $request Request Service + * @param string $parentType Parent Type owning images being saved + * @param \Thelia\Model\CategoryImage|\Thelia\Model\ProductImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage $model Image model + * @param array $data Post data * - * @return null|CategoryImageCreationForm|ContentImageCreationForm|FolderImageCreationForm|ProductImageCreationForm - * - * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + * @return ImageCreateOrUpdateEvent */ - public function getImageForm($parentType, Request $request) + private function createEventInstance($parentType, $model, $data) { - // @todo implement other forms - switch ($parentType) { -// case ImageCreateOrUpdateEvent::TYPE_PRODUCT: -// $creationForm = new ProductImageCreationForm($request); -// break; - case ImageCreateOrUpdateEvent::TYPE_CATEGORY: - $creationForm = new CategoryImageCreationForm($request); - break; -// case ImageCreateOrUpdateEvent::TYPE_CONTENT: -// $creationForm = new ContentImageCreationForm($request); -// break; -// case ImageCreateOrUpdateEvent::TYPE_FOLDER: -// $creationForm = new FolderImageCreationForm($request); -// break; - default: - $creationForm = null; + $imageCreateEvent = new ImageCreateOrUpdateEvent($parentType, null); + + if (isset($data['title'])) { + $model->setTitle($data['title']); + } + if (isset($data['chapo'])) { + $model->setChapo($data['chapo']); + } + if (isset($data['description'])) { + $model->setDescription($data['description']); + } + if (isset($data['file'])) { + $model->setFile($data['file']); + } + if (isset($data['postscriptum'])) { + $model->setPostscriptum($data['postscriptum']); } - return $creationForm; + $imageCreateEvent->setModelImage($model); + return $imageCreateEvent; } - /** - * Get image model from type - * - * @param string $parentType - * @param int $imageId - * - * @return null|\Thelia\Model\CategoryImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage|\Thelia\Model\ProductImage - * - * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action - */ - public function getImageModel($parentType, $imageId) - { - switch ($parentType) { - case ImageCreateOrUpdateEvent::TYPE_PRODUCT: - $model = ProductImageQuery::create()->findPk($imageId); - break; - case ImageCreateOrUpdateEvent::TYPE_CATEGORY: - $model = CategoryImageQuery::create()->findPk($imageId); - break; - case ImageCreateOrUpdateEvent::TYPE_CONTENT: - $model = ContentImageQuery::create()->findPk($imageId); - break; - case ImageCreateOrUpdateEvent::TYPE_FOLDER: - $model = FolderImageQuery::create()->findPk($imageId); - break; - default: - $model = null; - } - return $model; - - } } diff --git a/core/lib/Thelia/Core/Event/ImageCreateOrUpdateEvent.php b/core/lib/Thelia/Core/Event/ImageCreateOrUpdateEvent.php index afae53e7a..e7d5f3449 100755 --- a/core/lib/Thelia/Core/Event/ImageCreateOrUpdateEvent.php +++ b/core/lib/Thelia/Core/Event/ImageCreateOrUpdateEvent.php @@ -22,13 +22,14 @@ /*************************************************************************************/ namespace Thelia\Core\Event; +use Symfony\Component\HttpFoundation\File\UploadedFile; /** * Created by JetBrains PhpStorm. * Date: 9/18/13 * Time: 3:56 PM * - * Occurring when a Image list is saved + * Occurring when an Image is saved * * @package Image * @author Guillaume MOREL @@ -36,16 +37,15 @@ namespace Thelia\Core\Event; */ class ImageCreateOrUpdateEvent extends ActionEvent { - CONST TYPE_PRODUCT = 'product'; - CONST TYPE_CATEGORY = 'category'; - CONST TYPE_CONTENT = 'content'; - CONST TYPE_FOLDER = 'folder'; - /** @var array Images model to save */ - protected $modelImages = array(); + /** @var \Thelia\Model\CategoryImage|\Thelia\Model\ProductImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage model to save */ + protected $modelImage = array(); - /** @var array Images file to save */ - protected $uploadedFiles = array(); + /** @var \Thelia\Model\CategoryImage|\Thelia\Model\ProductImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage model to save */ + protected $oldModelImage = array(); + + /** @var UploadedFile Image file to save */ + protected $uploadedFile = null; /** @var int Image parent id */ protected $parentId = null; @@ -53,85 +53,56 @@ class ImageCreateOrUpdateEvent extends ActionEvent /** @var string Image type */ protected $imageType = null; - /** @var array Available image parent type */ - protected static $availableType = array( - self::TYPE_PRODUCT, - self::TYPE_CATEGORY, - self::TYPE_CONTENT, - self::TYPE_FOLDER, - ); + /** @var string Parent name */ + protected $parentName = null; /** * Constructor * - * @param string $pictureType Picture type - * ex : ImageCreateOrUpdateEvent::TYPE_CATEGORY + * @param string $imageType Image type + * ex : FileManager::TYPE_CATEGORY * @param int $parentId Image parent id */ - public function __construct($pictureType, $parentId) + public function __construct($imageType, $parentId) { - $this->imageType = $pictureType; + $this->imageType = $imageType; $this->parentId = $parentId; } /** - * Set Images to save + * Set Image to save * - * @param array $images Thelia\Model\CategoryImage Array + * @param $image \Thelia\Model\CategoryImage|\Thelia\Model\ProductImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage * * @return $this */ - public function setModelImages($images) + public function setModelImage($image) { - $this->modelImages = $images; + $this->modelImage = $image; return $this; } /** - * Get Images being saved + * Get Image being saved * - * @return array Array of Thelia\Model\CategoryImage + * @return \Thelia\Model\CategoryImage|\Thelia\Model\ProductImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage */ - public function getModelImages() + public function getModelImage() { - return $this->modelImages; - } - - /** - * Set Images to save - * - * @param array $images Thelia\Model\CategoryImage Array - * - * @return $this - */ - public function setUploadedFiles($images) - { - $this->uploadedFiles = $images; - - return $this; - } - - /** - * Get Images being saved - * - * @return array Array of Thelia\Model\CategoryImage - */ - public function getUploadedFiles() - { - return $this->uploadedFiles; + return $this->modelImage; } /** * Set picture type * - * @param string $pictureType Picture type + * @param string $imageType Image type * * @return $this */ - public function setImageType($pictureType) + public function setImageType($imageType) { - $this->imageType = $pictureType; + $this->imageType = $imageType; return $this; } @@ -146,16 +117,6 @@ class ImageCreateOrUpdateEvent extends ActionEvent return $this->imageType; } - /** - * Get all image parent type available - * - * @return array - */ - public static function getAvailableType() - { - return self::$availableType; - } - /** * Set Image parent id * @@ -180,5 +141,73 @@ class ImageCreateOrUpdateEvent extends ActionEvent return $this->parentId; } + /** + * Set uploaded file + * + * @param UploadedFile $uploadedFile File being uploaded + * + * @return $this + */ + public function setUploadedFile($uploadedFile) + { + $this->uploadedFile = $uploadedFile; + + return $this; + } + + /** + * Get uploaded file + * + * @return UploadedFile + */ + public function getUploadedFile() + { + return $this->uploadedFile; + } + + /** + * Set parent name + * + * @param string $parentName Parent name + * + * @return $this + */ + public function setParentName($parentName) + { + $this->parentName = $parentName; + + return $this; + } + + /** + * Get parent name + * + * @return string + */ + public function getParentName() + { + return $this->parentName; + } + + /** + * Set old model value + * + * @param \Thelia\Model\CategoryImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage|\Thelia\Model\ProductImage $oldModelImage + */ + public function setOldModelImage($oldModelImage) + { + $this->oldModelImage = $oldModelImage; + } + + /** + * Get old model value + * + * @return \Thelia\Model\CategoryImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage|\Thelia\Model\ProductImage + */ + public function getOldModelImage() + { + return $this->oldModelImage; + } + } diff --git a/core/lib/Thelia/Core/Event/ImageDeleteEvent.php b/core/lib/Thelia/Core/Event/ImageDeleteEvent.php index 54e042e79..9e890e999 100755 --- a/core/lib/Thelia/Core/Event/ImageDeleteEvent.php +++ b/core/lib/Thelia/Core/Event/ImageDeleteEvent.php @@ -41,6 +41,9 @@ use Thelia\Model\ProductImage; */ class ImageDeleteEvent extends ActionEvent { + /** @var string Image type */ + protected $imageType = null; + /** @var CategoryImage|ProductImage|ContentImage|FolderImage Image about to be deleted */ protected $imageToDelete = null; @@ -48,10 +51,37 @@ class ImageDeleteEvent extends ActionEvent * Constructor * * @param CategoryImage|ProductImage|ContentImage|FolderImage $imageToDelete Image about to be deleted + * @param string $imageType Image type + * ex : FileManager::TYPE_CATEGORY */ - public function __construct($imageToDelete) + public function __construct($imageToDelete, $imageType) { $this->imageToDelete = $imageToDelete; + $this->imageType = $imageType; + } + + /** + * Set picture type + * + * @param string $imageType Image type + * + * @return $this + */ + public function setImageType($imageType) + { + $this->imageType = $imageType; + + return $this; + } + + /** + * Get picture type + * + * @return string + */ + public function getImageType() + { + return $this->imageType; } /** diff --git a/core/lib/Thelia/Core/Event/ImagesCreateOrUpdateEvent.php b/core/lib/Thelia/Core/Event/ImagesCreateOrUpdateEvent.php new file mode 100755 index 000000000..62c189fc5 --- /dev/null +++ b/core/lib/Thelia/Core/Event/ImagesCreateOrUpdateEvent.php @@ -0,0 +1,184 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Occurring when a Image list is saved + * + * @package Image + * @author Guillaume MOREL + * + */ +class ImagesCreateOrUpdateEvent extends ActionEvent +{ + CONST TYPE_PRODUCT = 'product'; + CONST TYPE_CATEGORY = 'category'; + CONST TYPE_CONTENT = 'content'; + CONST TYPE_FOLDER = 'folder'; + + /** @var array Images model to save */ + protected $modelImages = array(); + + /** @var array Images file to save */ + protected $uploadedFiles = array(); + + /** @var int Image parent id */ + protected $parentId = null; + + /** @var string Image type */ + protected $imageType = null; + + /** @var array Available image parent type */ + protected static $availableType = array( + self::TYPE_PRODUCT, + self::TYPE_CATEGORY, + self::TYPE_CONTENT, + self::TYPE_FOLDER, + ); + + /** + * Constructor + * + * @param string $pictureType Picture type + * ex : ImageCreateOrUpdateEvent::TYPE_CATEGORY + * @param int $parentId Image parent id + */ + public function __construct($pictureType, $parentId) + { + $this->imageType = $pictureType; + $this->parentId = $parentId; + } + + /** + * Set Images to save + * + * @param array $images Thelia\Model\CategoryImage Array + * + * @return $this + */ + public function setModelImages($images) + { + $this->modelImages = $images; + + return $this; + } + + /** + * Get Images being saved + * + * @return array Array of Thelia\Model\CategoryImage + */ + public function getModelImages() + { + return $this->modelImages; + } + + /** + * Set Images to save + * + * @param array $images Thelia\Model\CategoryImage Array + * + * @return $this + */ + public function setUploadedFiles($images) + { + $this->uploadedFiles = $images; + + return $this; + } + + /** + * Get Images being saved + * + * @return array Array of Thelia\Model\CategoryImage + */ + public function getUploadedFiles() + { + return $this->uploadedFiles; + } + + /** + * Set picture type + * + * @param string $pictureType Picture type + * + * @return $this + */ + public function setImageType($pictureType) + { + $this->imageType = $pictureType; + + return $this; + } + + /** + * Get picture type + * + * @return string + */ + public function getImageType() + { + return $this->imageType; + } + + /** + * Get all image parent type available + * + * @return array + */ + public static function getAvailableType() + { + return self::$availableType; + } + + /** + * Set Image parent id + * + * @param int $parentId Image parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->parentId = $parentId; + + return $this; + } + + /** + * Get Image parent id + * + * @return int + */ + public function getParentId() + { + return $this->parentId; + } + + +} diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 7b47910d0..d41b6b5cd 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -304,6 +304,11 @@ final class TheliaEvents */ const IMAGE_SAVE = "action.saveImages"; + /** + * Save given images + */ + const IMAGE_UPDATE = "action.updateImages"; + /** * Delete given image */ diff --git a/core/lib/Thelia/Form/CategoryImageCreationForm.php b/core/lib/Thelia/Form/CategoryImageModification.php similarity index 75% rename from core/lib/Thelia/Form/CategoryImageCreationForm.php rename to core/lib/Thelia/Form/CategoryImageModification.php index d0b3be229..06674d9ef 100644 --- a/core/lib/Thelia/Form/CategoryImageCreationForm.php +++ b/core/lib/Thelia/Form/CategoryImageModification.php @@ -22,8 +22,9 @@ /*************************************************************************************/ namespace Thelia\Form; + use Thelia\Core\Translation\Translator; -use Thelia\Form\Type\ImageCategoryType; +use Thelia\Form\Image\ImageModification; /** * Created by JetBrains PhpStorm. @@ -36,36 +37,17 @@ use Thelia\Form\Type\ImageCategoryType; * @author Guillaume MOREL * */ -class CategoryImageCreationForm extends BaseForm +class CategoryImageModification extends ImageModification { - /** - * Allow to build a form - */ - protected function buildForm() - { - $this->formBuilder - ->add('pictures', - 'collection', - array( - 'type' => new ImageCategoryType(), - 'options' => array( - 'required' => false - ), - 'allow_add' => true, - 'allow_delete' => true, - 'by_reference' => false, - ) - ) - ->add('formSuccessUrl'); - } /** * Get form name + * This name must be unique * * @return string */ public function getName() { - return 'thelia_category_image_creation'; + return 'thelia_category_image_modification'; } } diff --git a/core/lib/Thelia/Form/Type/ImageCategoryType.php b/core/lib/Thelia/Form/ContentImageModification.php similarity index 66% rename from core/lib/Thelia/Form/Type/ImageCategoryType.php rename to core/lib/Thelia/Form/ContentImageModification.php index 7b8a3c474..f40fc5497 100644 --- a/core/lib/Thelia/Form/Type/ImageCategoryType.php +++ b/core/lib/Thelia/Form/ContentImageModification.php @@ -20,60 +20,34 @@ /* along with this program. If not, see . */ /* */ /*************************************************************************************/ -namespace Thelia\Form\Type; +namespace Thelia\Form; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolverInterface; -use Thelia\Form\Type\ImageType; + +use Thelia\Core\Translation\Translator; +use Thelia\Form\Image\ImageModification; /** * Created by JetBrains PhpStorm. * Date: 9/18/13 * Time: 3:56 PM * - * Form allowing to process a category picture + * Form allowing to process an image collection * * @package Image * @author Guillaume MOREL * */ -class ImageCategoryType extends ImageType +class ContentImageModification extends ImageModification { - /** - * Build a Picture form - * - * @param FormBuilderInterface $builder Form builder - * @param array $options Form options - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->add('category_id', 'integer'); - - parent::buildForm($builder, $options); - } - - /** - * Set default options - * Map the form to the given Model - * - * @param OptionsResolverInterface $resolver Option resolver - */ - public function setDefaultOptions(OptionsResolverInterface $resolver) - { - $resolver->setDefaults( - array( - 'data_class' => 'Thelia\Model\CategoryImage' - ) - ); - } /** * Get form name + * This name must be unique * * @return string */ public function getName() { - return 'thelia_category_picture_creation_type'; + return 'thelia_content_image_modification'; } } diff --git a/core/lib/Thelia/Form/Type/ImageType.php b/core/lib/Thelia/Form/FolderImageModification.php similarity index 58% rename from core/lib/Thelia/Form/Type/ImageType.php rename to core/lib/Thelia/Form/FolderImageModification.php index 662e2b3f7..a9305433b 100644 --- a/core/lib/Thelia/Form/Type/ImageType.php +++ b/core/lib/Thelia/Form/FolderImageModification.php @@ -20,63 +20,34 @@ /* along with this program. If not, see . */ /* */ /*************************************************************************************/ -namespace Thelia\Form\Type; +namespace Thelia\Form; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Validator\Constraints\Image; -use Symfony\Component\Validator\Constraints\NotBlank; + +use Thelia\Core\Translation\Translator; +use Thelia\Form\Image\ImageModification; /** * Created by JetBrains PhpStorm. * Date: 9/18/13 * Time: 3:56 PM * - * Form allowing to process a picture - * - * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + * Form allowing to process an image collection * * @package Image * @author Guillaume MOREL * */ -abstract class ImageType extends AbstractType +class FolderImageModification extends ImageModification { + /** - * Build a Picture form + * Get form name + * This name must be unique * - * @param FormBuilderInterface $builder Form builder - * @param array $options Form options + * @return string */ - public function buildForm(FormBuilderInterface $builder, array $options) + public function getName() { -// $builder->add('position'); - $builder->add( - 'title', - 'text', - array( - 'constraints' => new NotBlank() - ) - ); - $builder->add( - 'file', - 'file', - array( - 'constraints' => array( - new NotBlank(), - new Image( - array( - 'minWidth' => 200, -// 'maxWidth' => 400, - 'minHeight' => 200, -// 'maxHeight' => 400, - ) - ) - ) - ) - ); -// $builder->add('description'); -// $builder->add('chapo'); -// $builder->add('postscriptum'); + return 'thelia_folder_image_modification'; } } diff --git a/core/lib/Thelia/Form/Image/ImageModification.php b/core/lib/Thelia/Form/Image/ImageModification.php new file mode 100644 index 000000000..4d0d10694 --- /dev/null +++ b/core/lib/Thelia/Form/Image/ImageModification.php @@ -0,0 +1,183 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form\Image; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Validator\Constraints\Image; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; +use Thelia\Form\BaseForm; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process an image + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + * + * @package Image + * @author Guillaume MOREL + * + */ +abstract class ImageModification extends BaseForm +{ + +// public function __construct(Request $request, $type= "form", $data = array(), $options = array(), $isUpdate = false) +// { +// parent::__construct($request, $type, $data, $options); +// $this->setIsUpdate($isUpdate); +// } + +// /** @var bool Flag for update/create mode */ +// protected $isUpdate = false; + + /** + * + * in this function you add all the fields you need for your Form. + * Form this you have to call add method on $this->form attribute : + * + * $this->form->add('name', 'text') + * ->add('email', 'email', array( + * 'attr' => array( + * 'class' => 'field' + * ), + * 'label' => 'email', + * 'constraints' => array( + * new NotBlank() + * ) + * ) + * ) + * ->add('age', 'integer'); + * + * @return null + */ + protected function buildForm() + { +// if (false === $this->isUpdate) { + $this->formBuilder->add( + 'file', + 'file', + array( + 'constraints' => array( +// new NotBlank(), + new Image( + array( + 'minWidth' => 200, + 'minHeight' => 200 + ) + ) + ), + 'label' => Translator::getInstance()->trans('File'), + 'label_attr' => array( + 'for' => 'file' + ) + ) + ); +// } + + $this->formBuilder + ->add( + 'title', + 'text', + array( + 'constraints' => array( + new NotBlank() + ), + 'label' => Translator::getInstance()->trans('Title'), + 'label_attr' => array( + 'for' => 'title' + ) + ) + ) + ->add( + 'description', + 'text', + array( + 'constraints' => array(), + 'label' => Translator::getInstance()->trans('Description'), + 'label_attr' => array( + 'for' => 'description' + ) + ) + ) + ->add( + 'chapo', + 'text', + array( + 'constraints' => array(), + 'label' => Translator::getInstance()->trans('Chapo'), + 'label_attr' => array( + 'for' => 'chapo' + ) + ) + ) + ->add( + 'postscriptum', + 'text', + array( + 'constraints' => array(), + 'label' => Translator::getInstance()->trans('Post Scriptum'), + 'label_attr' => array( + 'for' => 'postscriptum' + ) + ) + ) + ->add( + 'postscriptum', + 'text', + array( + 'constraints' => array(), + 'label' => Translator::getInstance()->trans('Post Scriptum'), + 'label_attr' => array( + 'for' => 'postscriptum' + ) + ) + ); + + + } + +// /** +// * Set form in update or create mode +// * +// * @param boolean $isUpdate +// */ +// public function setIsUpdate($isUpdate) +// { +// $this->isUpdate = $isUpdate; +// } +// +// /** +// * Get for mode +// * +// * @return boolean +// */ +// public function getIsUpdate() +// { +// return $this->isUpdate; +// } + + + +} diff --git a/core/lib/Thelia/Form/ProductImageModification.php b/core/lib/Thelia/Form/ProductImageModification.php new file mode 100644 index 000000000..2d35e176f --- /dev/null +++ b/core/lib/Thelia/Form/ProductImageModification.php @@ -0,0 +1,53 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + + +use Thelia\Core\Translation\Translator; +use Thelia\Form\Image\ImageModification; + +/** + * Created by JetBrains PhpStorm. + * Date: 9/18/13 + * Time: 3:56 PM + * + * Form allowing to process an image collection + * + * @package Image + * @author Guillaume MOREL + * + */ +class ProductImageModification extends ImageModification +{ + + /** + * Get form name + * This name must be unique + * + * @return string + */ + public function getName() + { + return 'thelia_product_image_modification'; + } +} diff --git a/core/lib/Thelia/Model/CategoryImage.php b/core/lib/Thelia/Model/CategoryImage.php index bb7fa0dcb..17ee387b5 100755 --- a/core/lib/Thelia/Model/CategoryImage.php +++ b/core/lib/Thelia/Model/CategoryImage.php @@ -29,40 +29,17 @@ class CategoryImage extends BaseCategoryImage } /** - * Get picture absolute path - * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + * Set Image parent id * - * @return null|string - */ - public function getAbsolutePath() - { - return null === $this->file - ? null - : $this->getUploadDir().'/'.$this->file; - } - - /** - * Get picture web path - * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + * @param int $parentId parent id * - * @return null|string + * @return $this */ - public function getWebPath() + public function setParentId($parentId) { - return null === $this->file - ? null - : $this->getUploadDir().'/'.$this->file; - } + $this->setCategoryId($parentId); - - /** - * Get rid of the __DIR__ so it doesn't screw up - * when displaying uploaded doc/image in the view. - * @return string - */ - public function getUploadDir() - { - return THELIA_LOCAL_DIR . 'media/images/category'; + return $this; } /** diff --git a/core/lib/Thelia/Model/ContentImage.php b/core/lib/Thelia/Model/ContentImage.php index ddb33cbe8..b6a3085d4 100755 --- a/core/lib/Thelia/Model/ContentImage.php +++ b/core/lib/Thelia/Model/ContentImage.php @@ -26,6 +26,20 @@ class ContentImage extends BaseContentImage return true; } + /** + * Set Image parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setContentId($parentId); + + return $this; + } + /** * Get Image parent id * diff --git a/core/lib/Thelia/Model/FolderImage.php b/core/lib/Thelia/Model/FolderImage.php index 0983f0244..f9491c9a5 100755 --- a/core/lib/Thelia/Model/FolderImage.php +++ b/core/lib/Thelia/Model/FolderImage.php @@ -26,6 +26,20 @@ class FolderImage extends BaseFolderImage return true; } + /** + * Set Image parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setFolderId($parentId); + + return $this; + } + /** * Get Image parent id * diff --git a/core/lib/Thelia/Model/ProductImage.php b/core/lib/Thelia/Model/ProductImage.php index 058cbc863..6cc3ddd8c 100755 --- a/core/lib/Thelia/Model/ProductImage.php +++ b/core/lib/Thelia/Model/ProductImage.php @@ -26,6 +26,20 @@ class ProductImage extends BaseProductImage return true; } + /** + * Set Image parent id + * + * @param int $parentId parent id + * + * @return $this + */ + public function setParentId($parentId) + { + $this->setProductId($parentId); + + return $this; + } + /** * Get Image parent id * diff --git a/core/lib/Thelia/Tests/Tools/FileManagerTest.php b/core/lib/Thelia/Tests/Tools/FileManagerTest.php index 7ee1fd493..25ecd52af 100644 --- a/core/lib/Thelia/Tests/Tools/FileManagerTest.php +++ b/core/lib/Thelia/Tests/Tools/FileManagerTest.php @@ -10,7 +10,7 @@ namespace Thelia\Tests\Type; -use Thelia\Core\Event\ImageCreateOrUpdateEvent; +use Thelia\Core\Event\ImagesCreateOrUpdateEvent; use Thelia\Exception\ImageException; use Thelia\Model\Admin; use Thelia\Model\ProductImage; @@ -94,7 +94,7 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase { $newUploadedFiles = array(); - $actual = $fileManager->copyUploadedFile(24, ImageCreateOrUpdateEvent::TYPE_PRODUCT, $stubProductImage, $stubUploadedFile, $newUploadedFiles); + $actual = $fileManager->copyUploadedFile(24, ImagesCreateOrUpdateEvent::TYPE_PRODUCT, $stubProductImage, $stubUploadedFile, $newUploadedFiles); $this->assertCount(1, $actual); } @@ -176,7 +176,7 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase { $newUploadedFiles = array(); - $actual = $fileManager->copyUploadedFile(24, ImageCreateOrUpdateEvent::TYPE_PRODUCT, $stubProductImage, $stubUploadedFile, $newUploadedFiles); + $actual = $fileManager->copyUploadedFile(24, ImagesCreateOrUpdateEvent::TYPE_PRODUCT, $stubProductImage, $stubUploadedFile, $newUploadedFiles); } @@ -198,7 +198,7 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase { $fileManager = new FileManager($stubContainer); - $event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_PRODUCT, 24); + $event = new ImagesCreateOrUpdateEvent(ImagesCreateOrUpdateEvent::TYPE_PRODUCT, 24); $expected = 10; $actual = $fileManager->saveImage($event, $stubProductImage); @@ -224,7 +224,7 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase { $fileManager = new FileManager($stubContainer); - $event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_CATEGORY, 24); + $event = new ImagesCreateOrUpdateEvent(ImagesCreateOrUpdateEvent::TYPE_CATEGORY, 24); $expected = 10; $actual = $fileManager->saveImage($event, $stubCategoryImage); @@ -250,7 +250,7 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase { $fileManager = new FileManager($stubContainer); - $event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_FOLDER, 24); + $event = new ImagesCreateOrUpdateEvent(ImagesCreateOrUpdateEvent::TYPE_FOLDER, 24); $expected = 10; $actual = $fileManager->saveImage($event, $stubFolderImage); @@ -276,7 +276,7 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase { $fileManager = new FileManager($stubContainer); - $event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_CONTENT, 24); + $event = new ImagesCreateOrUpdateEvent(ImagesCreateOrUpdateEvent::TYPE_CONTENT, 24); $expected = 10; $actual = $fileManager->saveImage($event, $stubContentImage); @@ -302,7 +302,7 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase { ->method('save') ->will($this->returnValue(10)); - $event = new ImageCreateOrUpdateEvent('bad', 24); + $event = new ImagesCreateOrUpdateEvent('bad', 24); $modelImage = new ProductImage(); $fileManager->saveImage($event, $modelImage); @@ -326,7 +326,7 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase { ->method('save') ->will($this->returnValue(0)); - $event = new ImageCreateOrUpdateEvent(ImageCreateOrUpdateEvent::TYPE_PRODUCT, 24); + $event = new ImagesCreateOrUpdateEvent(ImagesCreateOrUpdateEvent::TYPE_PRODUCT, 24); $fileManager->saveImage($event, $stubProductImage); } diff --git a/core/lib/Thelia/Tools/FileManager.php b/core/lib/Thelia/Tools/FileManager.php index 533dcb203..4b1d90e89 100644 --- a/core/lib/Thelia/Tools/FileManager.php +++ b/core/lib/Thelia/Tools/FileManager.php @@ -24,14 +24,27 @@ namespace Thelia\Tools; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\File\UploadedFile; -use Thelia\Core\Event\ImageCreateOrUpdateEvent; -use Thelia\Core\Event\ImageDeleteEvent; +use Thelia\Core\Event\ImagesCreateOrUpdateEvent; +use Thelia\Core\HttpFoundation\Request; +use Thelia\Core\Translation\Translator; use Thelia\Exception\ImageException; +use Thelia\Form\CategoryImageModification; +use Thelia\Form\ContentImageModification; +use Thelia\Form\FolderImageModification; +use Thelia\Form\ProductImageModification; use Thelia\Model\AdminLog; -use Thelia\Model\Base\CategoryImage; +use Thelia\Model\CategoryImage; +use Thelia\Model\CategoryImageQuery; +use Thelia\Model\CategoryQuery; use Thelia\Model\ContentImage; +use Thelia\Model\ContentImageQuery; +use Thelia\Model\ContentQuery; use Thelia\Model\FolderImage; +use Thelia\Model\FolderImageQuery; +use Thelia\Model\FolderQuery; use Thelia\Model\ProductImage; +use Thelia\Model\ProductImageQuery; +use Thelia\Model\ProductQuery; /** * Created by JetBrains PhpStorm. @@ -46,6 +59,12 @@ use Thelia\Model\ProductImage; */ class FileManager { + CONST TYPE_PRODUCT = 'product'; + CONST TYPE_CATEGORY = 'category'; + CONST TYPE_CONTENT = 'content'; + CONST TYPE_FOLDER = 'folder'; + CONST TYPE_MODULE = 'module'; + /** @var ContainerInterface Service Container */ protected $container = null; @@ -70,20 +89,15 @@ class FileManager * @param string $imageType Image type * @param FolderImage|ContentImage|CategoryImage|ProductImage $modelImage Image saved * @param UploadedFile $uploadedFile Ready to be uploaded file - * @param array $newUploadedFiles UploadedFile array to update * * @throws \Thelia\Exception\ImageException - * @return array Updated UploadedFile array + * @return UploadedFile */ - public function copyUploadedFile($parentId, $imageType, $modelImage, $uploadedFile, $newUploadedFiles) + public function copyUploadedFile($parentId, $imageType, $modelImage, $uploadedFile) { if ($uploadedFile !== null) { - $directory = $modelImage->getUploadDir(); - $fileName = $this->sanitizeFileName( - $uploadedFile->getClientOriginalName() . "-" . $modelImage->getId() . "." . strtolower( - $uploadedFile->getClientOriginalExtension() - ) - ); + $directory = $this->getUploadDir($imageType); + $fileName = $this->renameFile($modelImage->getId(), $uploadedFile); $this->adminLogAppend( $this->translator->trans( @@ -98,7 +112,7 @@ class FileManager ) ); - $newUploadedFiles[] = array('file' => $uploadedFile->move($directory, $fileName)); + $newUploadedFile = $uploadedFile->move($directory, $fileName); $modelImage->setFile($fileName); if (!$modelImage->save()) { @@ -112,38 +126,38 @@ class FileManager } } - return $newUploadedFiles; + return $newUploadedFile; } /** * Save image into the database * - * @param ImageCreateOrUpdateEvent $event Image event + * @param ImagesCreateOrUpdateEvent $event Image event * @param FolderImage|ContentImage|CategoryImage|ProductImage $modelImage Image to save * * @return int Nb lines modified * @throws \Thelia\Exception\ImageException * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action */ - public function saveImage(ImageCreateOrUpdateEvent $event, $modelImage) + public function saveImage(ImagesCreateOrUpdateEvent $event, $modelImage) { $nbModifiedLines = 0; if ($modelImage->getFile() !== null) { switch ($event->getImageType()) { - case ImageCreateOrUpdateEvent::TYPE_PRODUCT: + case ImagesCreateOrUpdateEvent::TYPE_PRODUCT: /** @var ProductImage $modelImage */ $modelImage->setProductId($event->getParentId()); break; - case ImageCreateOrUpdateEvent::TYPE_CATEGORY: + case ImagesCreateOrUpdateEvent::TYPE_CATEGORY: /** @var CategoryImage $modelImage */ $modelImage->setCategoryId($event->getParentId()); break; - case ImageCreateOrUpdateEvent::TYPE_CONTENT: + case ImagesCreateOrUpdateEvent::TYPE_CONTENT: /** @var ContentImage $modelImage */ $modelImage->setContentId($event->getParentId()); break; - case ImageCreateOrUpdateEvent::TYPE_FOLDER: + case ImagesCreateOrUpdateEvent::TYPE_FOLDER: /** @var FolderImage $modelImage */ $modelImage->setFolderId($event->getParentId()); break; @@ -213,10 +227,227 @@ class FileManager * Delete image from file storage and database * * @param CategoryImage|ProductImage|ContentImage|FolderImage $imageModel Image being deleted + * @param string $parentType Parent type */ - public function deleteImage($imageModel) + public function deleteImage($imageModel, $parentType) { - unlink($imageModel->getAbsolutePath()); + $url = $this->getUploadDir($parentType) . '/' . $imageModel->getFile(); + unlink(str_replace('..', '', $url)); $imageModel->delete(); } + + + /** + * Get image model from type + * + * @param string $parentType Parent type + * + * @return null|\Thelia\Model\CategoryImage|\Thelia\Model\ContentImage|\Thelia\Model\FolderImage|\Thelia\Model\ProductImage + * + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + */ + public function getImageModel($parentType) + { + switch ($parentType) { + case ImagesCreateOrUpdateEvent::TYPE_PRODUCT: + $model = new ProductImage(); + break; + case ImagesCreateOrUpdateEvent::TYPE_CATEGORY: + $model = new CategoryImage(); + break; + case ImagesCreateOrUpdateEvent::TYPE_CONTENT: + $model = new ContentImage(); + break; + case ImagesCreateOrUpdateEvent::TYPE_FOLDER: + $model = new FolderImage(); + break; + default: + $model = null; + } + + return $model; + } + + /** + * Get image model query from type + * + * @param string $parentType + * + * @return null|\Thelia\Model\CategoryImageQuery|\Thelia\Model\ContentImageQuery|\Thelia\Model\FolderImageQuery|\Thelia\Model\ProductImageQuery + * + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + */ + public function getImageModelQuery($parentType) + { + switch ($parentType) { + case ImagesCreateOrUpdateEvent::TYPE_PRODUCT: + $model = new ProductImageQuery(); + break; + case ImagesCreateOrUpdateEvent::TYPE_CATEGORY: + $model = new CategoryImageQuery(); + break; + case ImagesCreateOrUpdateEvent::TYPE_CONTENT: + $model = new ContentImageQuery(); + break; + case ImagesCreateOrUpdateEvent::TYPE_FOLDER: + $model = new FolderImageQuery(); + break; + default: + $model = null; + } + + return $model; + } + + /** + * Get image parent model from type + * + * @param string $parentType + * @param int $parentId + * + * @return null|\Thelia\Model\Category|\Thelia\Model\Content|\Thelia\Model\Folder|\Thelia\Model\Product + * + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + */ + public function getParentImageModel($parentType, $parentId) + { + switch ($parentType) { + case ImagesCreateOrUpdateEvent::TYPE_PRODUCT: + $model = ProductQuery::create()->findPk($parentId); + break; + case ImagesCreateOrUpdateEvent::TYPE_CATEGORY: + $model = CategoryQuery::create()->findPk($parentId); + break; + case ImagesCreateOrUpdateEvent::TYPE_CONTENT: + $model = ContentQuery::create()->findPk($parentId); + break; + case ImagesCreateOrUpdateEvent::TYPE_FOLDER: + $model = FolderQuery::create()->findPk($parentId); + break; + default: + $model = null; + } + + return $model; + } + + /** + * Get image parent model from type + * + * @param string $parentType Parent type + * @param Request $request Request service + * + * @todo refactor make all pictures using propel inheritance and factorise image behaviour into one single clean action + * @return ProductImageModification|CategoryImageModification|ContentImageModification|FolderImageModification + */ + public function getImageForm($parentType, Request $request) + { + switch ($parentType) { + case ImagesCreateOrUpdateEvent::TYPE_PRODUCT: + $form = new ProductImageModification($request); + break; + case ImagesCreateOrUpdateEvent::TYPE_CATEGORY: + $form = new CategoryImageModification($request); + break; + case ImagesCreateOrUpdateEvent::TYPE_CONTENT: + $form = new ContentImageModification($request); + break; + case ImagesCreateOrUpdateEvent::TYPE_FOLDER: + $form = new FolderImageModification($request); + break; + default: + $model = null; + } + + return $form; + + } + + /** + * Get image upload dir + * + * @param string $parentType Parent type + * + * @return string Uri + */ + public function getUploadDir($parentType) + { + switch ($parentType) { + case ImagesCreateOrUpdateEvent::TYPE_PRODUCT: + $uri = THELIA_LOCAL_DIR . 'media/images/' . ImagesCreateOrUpdateEvent::TYPE_PRODUCT; + break; + case ImagesCreateOrUpdateEvent::TYPE_CATEGORY: + $uri = THELIA_LOCAL_DIR . 'media/images/' . ImagesCreateOrUpdateEvent::TYPE_CATEGORY; + break; + case ImagesCreateOrUpdateEvent::TYPE_CONTENT: + $uri = THELIA_LOCAL_DIR . 'media/images/' . ImagesCreateOrUpdateEvent::TYPE_CONTENT; + break; + case ImagesCreateOrUpdateEvent::TYPE_FOLDER: + $uri = THELIA_LOCAL_DIR . 'media/images/' . ImagesCreateOrUpdateEvent::TYPE_FOLDER; + break; + default: + $uri = null; + } + + return $uri; + + } + + /** + * Deduce image redirecting URL from parent type + * + * @param string $parentType Parent type + * @param int $parentId Parent id + * @return string + */ + public function getRedirectionUrl($parentType, $parentId) + { + switch ($parentType) { + case ImagesCreateOrUpdateEvent::TYPE_PRODUCT: + $uri = '/admin/products/update?product_id=' . $parentId; + break; + case ImagesCreateOrUpdateEvent::TYPE_CATEGORY: + $uri = '/admin/categories/update?category_id=' . $parentId; + break; + case ImagesCreateOrUpdateEvent::TYPE_CONTENT: + $uri = '/admin/content/update/' . $parentId; + break; + case ImagesCreateOrUpdateEvent::TYPE_FOLDER: + $uri = '/admin/folders/update?folder_id=' . $parentId; + break; + default: + $uri = false; + } + + return $uri; + + } + + /** @var array Available image parent type */ + public static $availableType = array( + self::TYPE_PRODUCT, + self::TYPE_CATEGORY, + self::TYPE_CONTENT, + self::TYPE_FOLDER, + self::TYPE_MODULE + ); + + /** + * Rename file with image model id + * + * @param int $modelId Model id + * @param UploadedFile $uploadedFile File being saved + * + * @return string + */ + public function renameFile($modelId, $uploadedFile) + { + $extension = $uploadedFile->getClientOriginalExtension(); + $fileName = $this->sanitizeFileName( + str_replace('.' . $extension, '', $uploadedFile->getClientOriginalName()) . "-" . $modelId . "." . strtolower( + $extension + ) + ); + return $fileName; + } } \ No newline at end of file diff --git a/local/modules/Cheque/images/cheque.png b/local/modules/Cheque/images/cheque.png old mode 100644 new mode 100755 diff --git a/local/modules/FakeCB/images/mastercard.png b/local/modules/FakeCB/images/mastercard.png old mode 100644 new mode 100755 diff --git a/local/modules/FakeCB/images/visa.png b/local/modules/FakeCB/images/visa.png old mode 100644 new mode 100755 diff --git a/templates/admin/default/assets/js/dropzone.js b/templates/admin/default/assets/js/dropzone.js new file mode 100644 index 000000000..3e68289ad --- /dev/null +++ b/templates/admin/default/assets/js/dropzone.js @@ -0,0 +1,1758 @@ +;(function(){ + + /** + * Require the given path. + * + * @param {String} path + * @return {Object} exports + * @api public + */ + + function require(path, parent, orig) { + var resolved = require.resolve(path); + + // lookup failed + if (null == resolved) { + orig = orig || path; + parent = parent || 'root'; + var err = new Error('Failed to require "' + orig + '" from "' + parent + '"'); + err.path = orig; + err.parent = parent; + err.require = true; + throw err; + } + + var module = require.modules[resolved]; + + // perform real require() + // by invoking the module's + // registered function + if (!module.exports) { + module.exports = {}; + module.client = module.component = true; + module.call(this, module.exports, require.relative(resolved), module); + } + + return module.exports; + } + + /** + * Registered modules. + */ + + require.modules = {}; + + /** + * Registered aliases. + */ + + require.aliases = {}; + + /** + * Resolve `path`. + * + * Lookup: + * + * - PATH/index.js + * - PATH.js + * - PATH + * + * @param {String} path + * @return {String} path or null + * @api private + */ + + require.resolve = function(path) { + if (path.charAt(0) === '/') path = path.slice(1); + + var paths = [ + path, + path + '.js', + path + '.json', + path + '/index.js', + path + '/index.json' + ]; + + for (var i = 0; i < paths.length; i++) { + var path = paths[i]; + if (require.modules.hasOwnProperty(path)) return path; + if (require.aliases.hasOwnProperty(path)) return require.aliases[path]; + } + }; + + /** + * Normalize `path` relative to the current path. + * + * @param {String} curr + * @param {String} path + * @return {String} + * @api private + */ + + require.normalize = function(curr, path) { + var segs = []; + + if ('.' != path.charAt(0)) return path; + + curr = curr.split('/'); + path = path.split('/'); + + for (var i = 0; i < path.length; ++i) { + if ('..' == path[i]) { + curr.pop(); + } else if ('.' != path[i] && '' != path[i]) { + segs.push(path[i]); + } + } + + return curr.concat(segs).join('/'); + }; + + /** + * Register module at `path` with callback `definition`. + * + * @param {String} path + * @param {Function} definition + * @api private + */ + + require.register = function(path, definition) { + require.modules[path] = definition; + }; + + /** + * Alias a module definition. + * + * @param {String} from + * @param {String} to + * @api private + */ + + require.alias = function(from, to) { + if (!require.modules.hasOwnProperty(from)) { + throw new Error('Failed to alias "' + from + '", it does not exist'); + } + require.aliases[to] = from; + }; + + /** + * Return a require function relative to the `parent` path. + * + * @param {String} parent + * @return {Function} + * @api private + */ + + require.relative = function(parent) { + var p = require.normalize(parent, '..'); + + /** + * lastIndexOf helper. + */ + + function lastIndexOf(arr, obj) { + var i = arr.length; + while (i--) { + if (arr[i] === obj) return i; + } + return -1; + } + + /** + * The relative require() itself. + */ + + function localRequire(path) { + var resolved = localRequire.resolve(path); + return require(resolved, parent, path); + } + + /** + * Resolve relative to the parent. + */ + + localRequire.resolve = function(path) { + var c = path.charAt(0); + if ('/' == c) return path.slice(1); + if ('.' == c) return require.normalize(p, path); + + // resolve deps by returning + // the dep in the nearest "deps" + // directory + var segs = parent.split('/'); + var i = lastIndexOf(segs, 'deps') + 1; + if (!i) i = 0; + path = segs.slice(0, i + 1).join('/') + '/deps/' + path; + return path; + }; + + /** + * Check if module is defined at `path`. + */ + + localRequire.exists = function(path) { + return require.modules.hasOwnProperty(localRequire.resolve(path)); + }; + + return localRequire; + }; + require.register("component-emitter/index.js", function(exports, require, module){ + + /** + * Expose `Emitter`. + */ + + module.exports = Emitter; + + /** + * Initialize a new `Emitter`. + * + * @api public + */ + + function Emitter(obj) { + if (obj) return mixin(obj); + }; + + /** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + + function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; + } + + /** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + Emitter.prototype.on = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks[event] = this._callbacks[event] || []) + .push(fn); + return this; + }; + + /** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + Emitter.prototype.once = function(event, fn){ + var self = this; + this._callbacks = this._callbacks || {}; + + function on() { + self.off(event, on); + fn.apply(this, arguments); + } + + fn._off = on; + this.on(event, on); + return this; + }; + + /** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + Emitter.prototype.off = + Emitter.prototype.removeListener = + Emitter.prototype.removeAllListeners = function(event, fn){ + this._callbacks = this._callbacks || {}; + var callbacks = this._callbacks[event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks[event]; + return this; + } + + // remove specific handler + var i = callbacks.indexOf(fn._off || fn); + if (~i) callbacks.splice(i, 1); + return this; + }; + + /** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + + Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; + }; + + /** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + + Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks[event] || []; + }; + + /** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + + Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; + }; + + }); + require.register("dropzone/index.js", function(exports, require, module){ + + + /** + * Exposing dropzone + */ + module.exports = require("./lib/dropzone.js"); + + }); + require.register("dropzone/lib/dropzone.js", function(exports, require, module){ + /* + # + # More info at [www.dropzonejs.com](http://www.dropzonejs.com) + # + # Copyright (c) 2012, Matias Meno + # + # Permission is hereby granted, free of charge, to any person obtaining a copy + # of this software and associated documentation files (the "Software"), to deal + # in the Software without restriction, including without limitation the rights + # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + # copies of the Software, and to permit persons to whom the Software is + # furnished to do so, subject to the following conditions: + # + # The above copyright notice and this permission notice shall be included in + # all copies or substantial portions of the Software. + # + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + # THE SOFTWARE. + # + */ + + + (function() { + var Dropzone, Em, camelize, contentLoaded, noop, without, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __slice = [].slice; + + Em = typeof Emitter !== "undefined" && Emitter !== null ? Emitter : require("emitter"); + + noop = function() {}; + + Dropzone = (function(_super) { + var extend; + + __extends(Dropzone, _super); + + /* + This is a list of all available events you can register on a dropzone object. + + You can register an event handler like this: + + dropzone.on("dragEnter", function() { }); + */ + + + Dropzone.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "selectedfiles", "addedfile", "removedfile", "thumbnail", "error", "errormultiple", "processing", "processingmultiple", "uploadprogress", "totaluploadprogress", "sending", "sendingmultiple", "success", "successmultiple", "canceled", "canceledmultiple", "complete", "completemultiple", "reset", "maxfilesexceeded"]; + + Dropzone.prototype.defaultOptions = { + url: null, + method: "post", + withCredentials: false, + parallelUploads: 2, + uploadMultiple: false, + maxFilesize: 256, + paramName: "file", + createImageThumbnails: true, + maxThumbnailFilesize: 10, + thumbnailWidth: 100, + thumbnailHeight: 100, + maxFiles: null, + params: {}, + clickable: true, + ignoreHiddenFiles: true, + acceptedFiles: null, + acceptedMimeTypes: null, + autoProcessQueue: true, + addRemoveLinks: false, + previewsContainer: null, + dictDefaultMessage: "Drop files here to upload", + dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.", + dictFallbackText: "Please use the fallback form below to upload your files like in the olden days.", + dictFileTooBig: "File is too big ({{filesize}}MB). Max filesize: {{maxFilesize}}MB.", + dictInvalidFileType: "You can't upload files of this type.", + dictResponseError: "Server responded with {{statusCode}} code.", + dictCancelUpload: "Cancel upload", + dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?", + dictRemoveFile: "Remove file", + dictRemoveFileConfirmation: null, + dictMaxFilesExceeded: "You can only upload {{maxFiles}} files.", + accept: function(file, done) { + return done(); + }, + init: function() { + return noop; + }, + forceFallback: false, + fallback: function() { + var child, messageElement, span, _i, _len, _ref; + this.element.className = "" + this.element.className + " dz-browser-not-supported"; + _ref = this.element.getElementsByTagName("div"); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + if (/(^| )dz-message($| )/.test(child.className)) { + messageElement = child; + child.className = "dz-message"; + continue; + } + } + if (!messageElement) { + messageElement = Dropzone.createElement("
"); + this.element.appendChild(messageElement); + } + span = messageElement.getElementsByTagName("span")[0]; + if (span) { + span.textContent = this.options.dictFallbackMessage; + } + return this.element.appendChild(this.getFallbackForm()); + }, + resize: function(file) { + var info, srcRatio, trgRatio; + info = { + srcX: 0, + srcY: 0, + srcWidth: file.width, + srcHeight: file.height + }; + srcRatio = file.width / file.height; + trgRatio = this.options.thumbnailWidth / this.options.thumbnailHeight; + if (file.height < this.options.thumbnailHeight || file.width < this.options.thumbnailWidth) { + info.trgHeight = info.srcHeight; + info.trgWidth = info.srcWidth; + } else { + if (srcRatio > trgRatio) { + info.srcHeight = file.height; + info.srcWidth = info.srcHeight * trgRatio; + } else { + info.srcWidth = file.width; + info.srcHeight = info.srcWidth / trgRatio; + } + } + info.srcX = (file.width - info.srcWidth) / 2; + info.srcY = (file.height - info.srcHeight) / 2; + return info; + }, + /* + Those functions register themselves to the events on init and handle all + the user interface specific stuff. Overwriting them won't break the upload + but can break the way it's displayed. + You can overwrite them if you don't like the default behavior. If you just + want to add an additional event handler, register it on the dropzone object + and don't overwrite those options. + */ + + drop: function(e) { + return this.element.classList.remove("dz-drag-hover"); + }, + dragstart: noop, + dragend: function(e) { + return this.element.classList.remove("dz-drag-hover"); + }, + dragenter: function(e) { + return this.element.classList.add("dz-drag-hover"); + }, + dragover: function(e) { + return this.element.classList.add("dz-drag-hover"); + }, + dragleave: function(e) { + return this.element.classList.remove("dz-drag-hover"); + }, + selectedfiles: function(files) { + if (this.element === this.previewsContainer) { + return this.element.classList.add("dz-started"); + } + }, + reset: function() { + return this.element.classList.remove("dz-started"); + }, + addedfile: function(file) { + var _this = this; + file.previewElement = Dropzone.createElement(this.options.previewTemplate); + file.previewTemplate = file.previewElement; + this.previewsContainer.appendChild(file.previewElement); + file.previewElement.querySelector("[data-dz-name]").textContent = file.name; + file.previewElement.querySelector("[data-dz-size]").innerHTML = this.filesize(file.size); + if (this.options.addRemoveLinks) { + file._removeLink = Dropzone.createElement("" + this.options.dictRemoveFile + ""); + file._removeLink.addEventListener("click", function(e) { + e.preventDefault(); + e.stopPropagation(); + if (file.status === Dropzone.UPLOADING) { + return Dropzone.confirm(_this.options.dictCancelUploadConfirmation, function() { + return _this.removeFile(file); + }); + } else { + if (_this.options.dictRemoveFileConfirmation) { + return Dropzone.confirm(_this.options.dictRemoveFileConfirmation, function() { + return _this.removeFile(file); + }); + } else { + return _this.removeFile(file); + } + } + }); + file.previewElement.appendChild(file._removeLink); + } + return this._updateMaxFilesReachedClass(); + }, + removedfile: function(file) { + var _ref; + if ((_ref = file.previewElement) != null) { + _ref.parentNode.removeChild(file.previewElement); + } + return this._updateMaxFilesReachedClass(); + }, + thumbnail: function(file, dataUrl) { + var thumbnailElement; + file.previewElement.classList.remove("dz-file-preview"); + file.previewElement.classList.add("dz-image-preview"); + thumbnailElement = file.previewElement.querySelector("[data-dz-thumbnail]"); + thumbnailElement.alt = file.name; + return thumbnailElement.src = dataUrl; + }, + error: function(file, message) { + file.previewElement.classList.add("dz-error"); + return file.previewElement.querySelector("[data-dz-errormessage]").textContent = message; + }, + errormultiple: noop, + processing: function(file) { + file.previewElement.classList.add("dz-processing"); + if (file._removeLink) { + return file._removeLink.textContent = this.options.dictCancelUpload; + } + }, + processingmultiple: noop, + uploadprogress: function(file, progress, bytesSent) { + return file.previewElement.querySelector("[data-dz-uploadprogress]").style.width = "" + progress + "%"; + }, + totaluploadprogress: noop, + sending: noop, + sendingmultiple: noop, + success: function(file) { + return file.previewElement.classList.add("dz-success"); + }, + successmultiple: noop, + canceled: function(file) { + return this.emit("error", file, "Upload canceled."); + }, + canceledmultiple: noop, + complete: function(file) { + if (file._removeLink) { + return file._removeLink.textContent = this.options.dictRemoveFile; + } + }, + completemultiple: noop, + maxfilesexceeded: noop, + previewTemplate: "
\n
\n
\n
\n \n
\n
\n
\n
\n
\n
" + }; + + extend = function() { + var key, object, objects, target, val, _i, _len; + target = arguments[0], objects = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + for (_i = 0, _len = objects.length; _i < _len; _i++) { + object = objects[_i]; + for (key in object) { + val = object[key]; + target[key] = val; + } + } + return target; + }; + + function Dropzone(element, options) { + var elementOptions, fallback, _ref; + this.element = element; + this.version = Dropzone.version; + this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\n*/g, ""); + this.clickableElements = []; + this.listeners = []; + this.files = []; + if (typeof this.element === "string") { + this.element = document.querySelector(this.element); + } + if (!(this.element && (this.element.nodeType != null))) { + throw new Error("Invalid dropzone element."); + } + if (this.element.dropzone) { + throw new Error("Dropzone already attached."); + } + Dropzone.instances.push(this); + element.dropzone = this; + elementOptions = (_ref = Dropzone.optionsForElement(this.element)) != null ? _ref : {}; + this.options = extend({}, this.defaultOptions, elementOptions, options != null ? options : {}); + if (this.options.forceFallback || !Dropzone.isBrowserSupported()) { + return this.options.fallback.call(this); + } + if (this.options.url == null) { + this.options.url = this.element.getAttribute("action"); + } + if (!this.options.url) { + throw new Error("No URL provided."); + } + if (this.options.acceptedFiles && this.options.acceptedMimeTypes) { + throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated."); + } + if (this.options.acceptedMimeTypes) { + this.options.acceptedFiles = this.options.acceptedMimeTypes; + delete this.options.acceptedMimeTypes; + } + this.options.method = this.options.method.toUpperCase(); + if ((fallback = this.getExistingFallback()) && fallback.parentNode) { + fallback.parentNode.removeChild(fallback); + } + if (this.options.previewsContainer) { + this.previewsContainer = Dropzone.getElement(this.options.previewsContainer, "previewsContainer"); + } else { + this.previewsContainer = this.element; + } + if (this.options.clickable) { + if (this.options.clickable === true) { + this.clickableElements = [this.element]; + } else { + this.clickableElements = Dropzone.getElements(this.options.clickable, "clickable"); + } + } + this.init(); + } + + Dropzone.prototype.getAcceptedFiles = function() { + var file, _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.accepted) { + _results.push(file); + } + } + return _results; + }; + + Dropzone.prototype.getRejectedFiles = function() { + var file, _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (!file.accepted) { + _results.push(file); + } + } + return _results; + }; + + Dropzone.prototype.getQueuedFiles = function() { + var file, _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.status === Dropzone.QUEUED) { + _results.push(file); + } + } + return _results; + }; + + Dropzone.prototype.getUploadingFiles = function() { + var file, _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.status === Dropzone.UPLOADING) { + _results.push(file); + } + } + return _results; + }; + + Dropzone.prototype.init = function() { + var eventName, noPropagation, setupHiddenFileInput, _i, _len, _ref, _ref1, + _this = this; + if (this.element.tagName === "form") { + this.element.setAttribute("enctype", "multipart/form-data"); + } + if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) { + this.element.appendChild(Dropzone.createElement("
" + this.options.dictDefaultMessage + "
")); + } + if (this.clickableElements.length) { + setupHiddenFileInput = function() { + if (_this.hiddenFileInput) { + document.body.removeChild(_this.hiddenFileInput); + } + _this.hiddenFileInput = document.createElement("input"); + _this.hiddenFileInput.setAttribute("type", "file"); + _this.hiddenFileInput.setAttribute("multiple", "multiple"); + if (_this.options.acceptedFiles != null) { + _this.hiddenFileInput.setAttribute("accept", _this.options.acceptedFiles); + } + _this.hiddenFileInput.style.visibility = "hidden"; + _this.hiddenFileInput.style.position = "absolute"; + _this.hiddenFileInput.style.top = "0"; + _this.hiddenFileInput.style.left = "0"; + _this.hiddenFileInput.style.height = "0"; + _this.hiddenFileInput.style.width = "0"; + document.body.appendChild(_this.hiddenFileInput); + return _this.hiddenFileInput.addEventListener("change", function() { + var files; + files = _this.hiddenFileInput.files; + if (files.length) { + _this.emit("selectedfiles", files); + _this.handleFiles(files); + } + return setupHiddenFileInput(); + }); + }; + setupHiddenFileInput(); + } + this.URL = (_ref = window.URL) != null ? _ref : window.webkitURL; + _ref1 = this.events; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + eventName = _ref1[_i]; + this.on(eventName, this.options[eventName]); + } + this.on("uploadprogress", function() { + return _this.updateTotalUploadProgress(); + }); + this.on("removedfile", function() { + return _this.updateTotalUploadProgress(); + }); + this.on("canceled", function(file) { + return _this.emit("complete", file); + }); + noPropagation = function(e) { + e.stopPropagation(); + if (e.preventDefault) { + return e.preventDefault(); + } else { + return e.returnValue = false; + } + }; + this.listeners = [ + { + element: this.element, + events: { + "dragstart": function(e) { + return _this.emit("dragstart", e); + }, + "dragenter": function(e) { + noPropagation(e); + return _this.emit("dragenter", e); + }, + "dragover": function(e) { + noPropagation(e); + return _this.emit("dragover", e); + }, + "dragleave": function(e) { + return _this.emit("dragleave", e); + }, + "drop": function(e) { + noPropagation(e); + return _this.drop(e); + }, + "dragend": function(e) { + return _this.emit("dragend", e); + } + } + } + ]; + this.clickableElements.forEach(function(clickableElement) { + return _this.listeners.push({ + element: clickableElement, + events: { + "click": function(evt) { + if ((clickableElement !== _this.element) || (evt.target === _this.element || Dropzone.elementInside(evt.target, _this.element.querySelector(".dz-message")))) { + return _this.hiddenFileInput.click(); + } + } + } + }); + }); + this.enable(); + return this.options.init.call(this); + }; + + Dropzone.prototype.destroy = function() { + var _ref; + this.disable(); + this.removeAllFiles(true); + if ((_ref = this.hiddenFileInput) != null ? _ref.parentNode : void 0) { + this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput); + this.hiddenFileInput = null; + } + return delete this.element.dropzone; + }; + + Dropzone.prototype.updateTotalUploadProgress = function() { + var acceptedFiles, file, totalBytes, totalBytesSent, totalUploadProgress, _i, _len, _ref; + totalBytesSent = 0; + totalBytes = 0; + acceptedFiles = this.getAcceptedFiles(); + if (acceptedFiles.length) { + _ref = this.getAcceptedFiles(); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + totalBytesSent += file.upload.bytesSent; + totalBytes += file.upload.total; + } + totalUploadProgress = 100 * totalBytesSent / totalBytes; + } else { + totalUploadProgress = 100; + } + return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent); + }; + + Dropzone.prototype.getFallbackForm = function() { + var existingFallback, fields, fieldsString, form; + if (existingFallback = this.getExistingFallback()) { + return existingFallback; + } + fieldsString = "
"; + if (this.options.dictFallbackText) { + fieldsString += "

" + this.options.dictFallbackText + "

"; + } + fieldsString += "
"; + fields = Dropzone.createElement(fieldsString); + if (this.element.tagName !== "FORM") { + form = Dropzone.createElement(""); + form.appendChild(fields); + } else { + this.element.setAttribute("enctype", "multipart/form-data"); + this.element.setAttribute("method", this.options.method); + } + return form != null ? form : fields; + }; + + Dropzone.prototype.getExistingFallback = function() { + var fallback, getFallback, tagName, _i, _len, _ref; + getFallback = function(elements) { + var el, _i, _len; + for (_i = 0, _len = elements.length; _i < _len; _i++) { + el = elements[_i]; + if (/(^| )fallback($| )/.test(el.className)) { + return el; + } + } + }; + _ref = ["div", "form"]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + tagName = _ref[_i]; + if (fallback = getFallback(this.element.getElementsByTagName(tagName))) { + return fallback; + } + } + }; + + Dropzone.prototype.setupEventListeners = function() { + var elementListeners, event, listener, _i, _len, _ref, _results; + _ref = this.listeners; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + elementListeners = _ref[_i]; + _results.push((function() { + var _ref1, _results1; + _ref1 = elementListeners.events; + _results1 = []; + for (event in _ref1) { + listener = _ref1[event]; + _results1.push(elementListeners.element.addEventListener(event, listener, false)); + } + return _results1; + })()); + } + return _results; + }; + + Dropzone.prototype.removeEventListeners = function() { + var elementListeners, event, listener, _i, _len, _ref, _results; + _ref = this.listeners; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + elementListeners = _ref[_i]; + _results.push((function() { + var _ref1, _results1; + _ref1 = elementListeners.events; + _results1 = []; + for (event in _ref1) { + listener = _ref1[event]; + _results1.push(elementListeners.element.removeEventListener(event, listener, false)); + } + return _results1; + })()); + } + return _results; + }; + + Dropzone.prototype.disable = function() { + var file, _i, _len, _ref, _results; + this.clickableElements.forEach(function(element) { + return element.classList.remove("dz-clickable"); + }); + this.removeEventListeners(); + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + _results.push(this.cancelUpload(file)); + } + return _results; + }; + + Dropzone.prototype.enable = function() { + this.clickableElements.forEach(function(element) { + return element.classList.add("dz-clickable"); + }); + return this.setupEventListeners(); + }; + + Dropzone.prototype.filesize = function(size) { + var string; + if (size >= 100000000000) { + size = size / 100000000000; + string = "TB"; + } else if (size >= 100000000) { + size = size / 100000000; + string = "GB"; + } else if (size >= 100000) { + size = size / 100000; + string = "MB"; + } else if (size >= 100) { + size = size / 100; + string = "KB"; + } else { + size = size * 10; + string = "b"; + } + return "" + (Math.round(size) / 10) + " " + string; + }; + + Dropzone.prototype._updateMaxFilesReachedClass = function() { + if (this.options.maxFiles && this.getAcceptedFiles().length >= this.options.maxFiles) { + return this.element.classList.add("dz-max-files-reached"); + } else { + return this.element.classList.remove("dz-max-files-reached"); + } + }; + + Dropzone.prototype.drop = function(e) { + var files, items; + if (!e.dataTransfer) { + return; + } + this.emit("drop", e); + files = e.dataTransfer.files; + this.emit("selectedfiles", files); + if (files.length) { + items = e.dataTransfer.items; + if (items && items.length && ((items[0].webkitGetAsEntry != null) || (items[0].getAsEntry != null))) { + this.handleItems(items); + } else { + this.handleFiles(files); + } + } + }; + + Dropzone.prototype.handleFiles = function(files) { + var file, _i, _len, _results; + _results = []; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + _results.push(this.addFile(file)); + } + return _results; + }; + + Dropzone.prototype.handleItems = function(items) { + var entry, item, _i, _len; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if (item.webkitGetAsEntry != null) { + entry = item.webkitGetAsEntry(); + if (entry.isFile) { + this.addFile(item.getAsFile()); + } else if (entry.isDirectory) { + this.addDirectory(entry, entry.name); + } + } else { + this.addFile(item.getAsFile()); + } + } + }; + + Dropzone.prototype.accept = function(file, done) { + if (file.size > this.options.maxFilesize * 1024 * 1024) { + return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize)); + } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) { + return done(this.options.dictInvalidFileType); + } else if (this.options.maxFiles && this.getAcceptedFiles().length >= this.options.maxFiles) { + done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles)); + return this.emit("maxfilesexceeded", file); + } else { + return this.options.accept.call(this, file, done); + } + }; + + Dropzone.prototype.addFile = function(file) { + var _this = this; + file.upload = { + progress: 0, + total: file.size, + bytesSent: 0 + }; + this.files.push(file); + file.status = Dropzone.ADDED; + this.emit("addedfile", file); + if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) { + this.createThumbnail(file); + } + return this.accept(file, function(error) { + if (error) { + file.accepted = false; + return _this._errorProcessing([file], error); + } else { + return _this.enqueueFile(file); + } + }); + }; + + Dropzone.prototype.enqueueFiles = function(files) { + var file, _i, _len; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + this.enqueueFile(file); + } + return null; + }; + + Dropzone.prototype.enqueueFile = function(file) { + var _this = this; + file.accepted = true; + if (file.status === Dropzone.ADDED) { + file.status = Dropzone.QUEUED; + if (this.options.autoProcessQueue) { + return setTimeout((function() { + return _this.processQueue(); + }), 1); + } + } else { + throw new Error("This file can't be queued because it has already been processed or was rejected."); + } + }; + + Dropzone.prototype.addDirectory = function(entry, path) { + var dirReader, entriesReader, + _this = this; + dirReader = entry.createReader(); + entriesReader = function(entries) { + var _i, _len; + for (_i = 0, _len = entries.length; _i < _len; _i++) { + entry = entries[_i]; + if (entry.isFile) { + entry.file(function(file) { + if (_this.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') { + return; + } + file.fullPath = "" + path + "/" + file.name; + return _this.addFile(file); + }); + } else if (entry.isDirectory) { + _this.addDirectory(entry, "" + path + "/" + entry.name); + } + } + }; + return dirReader.readEntries(entriesReader, function(error) { + return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(error) : void 0 : void 0; + }); + }; + + Dropzone.prototype.removeFile = function(file) { + if (file.status === Dropzone.UPLOADING) { + this.cancelUpload(file); + } + this.files = without(this.files, file); + this.emit("removedfile", file); + if (this.files.length === 0) { + return this.emit("reset"); + } + }; + + Dropzone.prototype.removeAllFiles = function(cancelIfNecessary) { + var file, _i, _len, _ref; + if (cancelIfNecessary == null) { + cancelIfNecessary = false; + } + _ref = this.files.slice(); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) { + this.removeFile(file); + } + } + return null; + }; + + Dropzone.prototype.createThumbnail = function(file) { + var fileReader, + _this = this; + fileReader = new FileReader; + fileReader.onload = function() { + var img; + img = new Image; + img.onload = function() { + var canvas, ctx, resizeInfo, thumbnail, _ref, _ref1, _ref2, _ref3; + file.width = img.width; + file.height = img.height; + resizeInfo = _this.options.resize.call(_this, file); + if (resizeInfo.trgWidth == null) { + resizeInfo.trgWidth = _this.options.thumbnailWidth; + } + if (resizeInfo.trgHeight == null) { + resizeInfo.trgHeight = _this.options.thumbnailHeight; + } + canvas = document.createElement("canvas"); + ctx = canvas.getContext("2d"); + canvas.width = resizeInfo.trgWidth; + canvas.height = resizeInfo.trgHeight; + ctx.drawImage(img, (_ref = resizeInfo.srcX) != null ? _ref : 0, (_ref1 = resizeInfo.srcY) != null ? _ref1 : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, (_ref2 = resizeInfo.trgX) != null ? _ref2 : 0, (_ref3 = resizeInfo.trgY) != null ? _ref3 : 0, resizeInfo.trgWidth, resizeInfo.trgHeight); + thumbnail = canvas.toDataURL("image/png"); + return _this.emit("thumbnail", file, thumbnail); + }; + return img.src = fileReader.result; + }; + return fileReader.readAsDataURL(file); + }; + + Dropzone.prototype.processQueue = function() { + var i, parallelUploads, processingLength, queuedFiles; + parallelUploads = this.options.parallelUploads; + processingLength = this.getUploadingFiles().length; + i = processingLength; + if (processingLength >= parallelUploads) { + return; + } + queuedFiles = this.getQueuedFiles(); + if (!(queuedFiles.length > 0)) { + return; + } + if (this.options.uploadMultiple) { + return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength)); + } else { + while (i < parallelUploads) { + if (!queuedFiles.length) { + return; + } + this.processFile(queuedFiles.shift()); + i++; + } + } + }; + + Dropzone.prototype.processFile = function(file) { + return this.processFiles([file]); + }; + + Dropzone.prototype.processFiles = function(files) { + var file, _i, _len; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + file.processing = true; + file.status = Dropzone.UPLOADING; + this.emit("processing", file); + } + if (this.options.uploadMultiple) { + this.emit("processingmultiple", files); + } + return this.uploadFiles(files); + }; + + Dropzone.prototype._getFilesWithXhr = function(xhr) { + var file, files; + return files = (function() { + var _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.xhr === xhr) { + _results.push(file); + } + } + return _results; + }).call(this); + }; + + Dropzone.prototype.cancelUpload = function(file) { + var groupedFile, groupedFiles, _i, _j, _len, _len1, _ref; + if (file.status === Dropzone.UPLOADING) { + groupedFiles = this._getFilesWithXhr(file.xhr); + for (_i = 0, _len = groupedFiles.length; _i < _len; _i++) { + groupedFile = groupedFiles[_i]; + groupedFile.status = Dropzone.CANCELED; + } + file.xhr.abort(); + for (_j = 0, _len1 = groupedFiles.length; _j < _len1; _j++) { + groupedFile = groupedFiles[_j]; + this.emit("canceled", groupedFile); + } + if (this.options.uploadMultiple) { + this.emit("canceledmultiple", groupedFiles); + } + } else if ((_ref = file.status) === Dropzone.ADDED || _ref === Dropzone.QUEUED) { + file.status = Dropzone.CANCELED; + this.emit("canceled", file); + if (this.options.uploadMultiple) { + this.emit("canceledmultiple", [file]); + } + } + if (this.options.autoProcessQueue) { + return this.processQueue(); + } + }; + + Dropzone.prototype.uploadFile = function(file) { + return this.uploadFiles([file]); + }; + + Dropzone.prototype.uploadFiles = function(files) { + var file, formData, handleError, headerName, headerValue, headers, input, inputName, inputType, key, progressObj, response, updateProgress, value, xhr, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, + _this = this; + xhr = new XMLHttpRequest(); + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + file.xhr = xhr; + } + xhr.open(this.options.method, this.options.url, true); + xhr.withCredentials = !!this.options.withCredentials; + response = null; + handleError = function() { + var _j, _len1, _results; + _results = []; + for (_j = 0, _len1 = files.length; _j < _len1; _j++) { + file = files[_j]; + _results.push(_this._errorProcessing(files, response || _this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr)); + } + return _results; + }; + updateProgress = function(e) { + var allFilesFinished, progress, _j, _k, _l, _len1, _len2, _len3, _results; + if (e != null) { + progress = 100 * e.loaded / e.total; + for (_j = 0, _len1 = files.length; _j < _len1; _j++) { + file = files[_j]; + file.upload = { + progress: progress, + total: e.total, + bytesSent: e.loaded + }; + } + } else { + allFilesFinished = true; + progress = 100; + for (_k = 0, _len2 = files.length; _k < _len2; _k++) { + file = files[_k]; + if (!(file.upload.progress === 100 && file.upload.bytesSent === file.upload.total)) { + allFilesFinished = false; + } + file.upload.progress = progress; + file.upload.bytesSent = file.upload.total; + } + if (allFilesFinished) { + return; + } + } + _results = []; + for (_l = 0, _len3 = files.length; _l < _len3; _l++) { + file = files[_l]; + _results.push(_this.emit("uploadprogress", file, progress, file.upload.bytesSent)); + } + return _results; + }; + xhr.onload = function(e) { + var _ref; + if (files[0].status === Dropzone.CANCELED) { + return; + } + if (xhr.readyState !== 4) { + return; + } + response = xhr.responseText; + if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) { + try { + response = JSON.parse(response); + } catch (_error) { + e = _error; + response = "Invalid JSON response from server."; + } + } + updateProgress(); + if (!((200 <= (_ref = xhr.status) && _ref < 300))) { + return handleError(); + } else { + return _this._finished(files, response, e); + } + }; + xhr.onerror = function() { + if (files[0].status === Dropzone.CANCELED) { + return; + } + return handleError(); + }; + progressObj = (_ref = xhr.upload) != null ? _ref : xhr; + progressObj.onprogress = updateProgress; + headers = { + "Accept": "application/json", + "Cache-Control": "no-cache", + "X-Requested-With": "XMLHttpRequest" + }; + if (this.options.headers) { + extend(headers, this.options.headers); + } + for (headerName in headers) { + headerValue = headers[headerName]; + xhr.setRequestHeader(headerName, headerValue); + } + formData = new FormData(); + if (this.options.params) { + _ref1 = this.options.params; + for (key in _ref1) { + value = _ref1[key]; + formData.append(key, value); + } + } + for (_j = 0, _len1 = files.length; _j < _len1; _j++) { + file = files[_j]; + this.emit("sending", file, xhr, formData); + } + if (this.options.uploadMultiple) { + this.emit("sendingmultiple", files, xhr, formData); + } + if (this.element.tagName === "FORM") { + _ref2 = this.element.querySelectorAll("input, textarea, select, button"); + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + input = _ref2[_k]; + inputName = input.getAttribute("name"); + inputType = input.getAttribute("type"); + if (!inputType || ((_ref3 = inputType.toLowerCase()) !== "checkbox" && _ref3 !== "radio") || input.checked) { + formData.append(inputName, input.value); + } + } + } + for (_l = 0, _len3 = files.length; _l < _len3; _l++) { + file = files[_l]; + formData.append("" + this.options.paramName + (this.options.uploadMultiple ? "[]" : ""), file, file.name); + } + return xhr.send(formData); + }; + + Dropzone.prototype._finished = function(files, responseText, e) { + var file, _i, _len; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + file.status = Dropzone.SUCCESS; + this.emit("success", file, responseText, e); + this.emit("complete", file); + } + if (this.options.uploadMultiple) { + this.emit("successmultiple", files, responseText, e); + this.emit("completemultiple", files); + } + if (this.options.autoProcessQueue) { + return this.processQueue(); + } + }; + + Dropzone.prototype._errorProcessing = function(files, message, xhr) { + var file, _i, _len; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + file.status = Dropzone.ERROR; + this.emit("error", file, message, xhr); + this.emit("complete", file); + } + if (this.options.uploadMultiple) { + this.emit("errormultiple", files, message, xhr); + this.emit("completemultiple", files); + } + if (this.options.autoProcessQueue) { + return this.processQueue(); + } + }; + + return Dropzone; + + })(Em); + + Dropzone.version = "3.7.1"; + + Dropzone.options = {}; + + Dropzone.optionsForElement = function(element) { + if (element.id) { + return Dropzone.options[camelize(element.id)]; + } else { + return void 0; + } + }; + + Dropzone.instances = []; + + Dropzone.forElement = function(element) { + if (typeof element === "string") { + element = document.querySelector(element); + } + if ((element != null ? element.dropzone : void 0) == null) { + throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone."); + } + return element.dropzone; + }; + + Dropzone.autoDiscover = true; + + Dropzone.discover = function() { + var checkElements, dropzone, dropzones, _i, _len, _results; + if (document.querySelectorAll) { + dropzones = document.querySelectorAll(".dropzone"); + } else { + dropzones = []; + checkElements = function(elements) { + var el, _i, _len, _results; + _results = []; + for (_i = 0, _len = elements.length; _i < _len; _i++) { + el = elements[_i]; + if (/(^| )dropzone($| )/.test(el.className)) { + _results.push(dropzones.push(el)); + } else { + _results.push(void 0); + } + } + return _results; + }; + checkElements(document.getElementsByTagName("div")); + checkElements(document.getElementsByTagName("form")); + } + _results = []; + for (_i = 0, _len = dropzones.length; _i < _len; _i++) { + dropzone = dropzones[_i]; + if (Dropzone.optionsForElement(dropzone) !== false) { + _results.push(new Dropzone(dropzone)); + } else { + _results.push(void 0); + } + } + return _results; + }; + + Dropzone.blacklistedBrowsers = [/opera.*Macintosh.*version\/12/i]; + + Dropzone.isBrowserSupported = function() { + var capableBrowser, regex, _i, _len, _ref; + capableBrowser = true; + if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) { + if (!("classList" in document.createElement("a"))) { + capableBrowser = false; + } else { + _ref = Dropzone.blacklistedBrowsers; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + regex = _ref[_i]; + if (regex.test(navigator.userAgent)) { + capableBrowser = false; + continue; + } + } + } + } else { + capableBrowser = false; + } + return capableBrowser; + }; + + without = function(list, rejectedItem) { + var item, _i, _len, _results; + _results = []; + for (_i = 0, _len = list.length; _i < _len; _i++) { + item = list[_i]; + if (item !== rejectedItem) { + _results.push(item); + } + } + return _results; + }; + + camelize = function(str) { + return str.replace(/[\-_](\w)/g, function(match) { + return match[1].toUpperCase(); + }); + }; + + Dropzone.createElement = function(string) { + var div; + div = document.createElement("div"); + div.innerHTML = string; + return div.childNodes[0]; + }; + + Dropzone.elementInside = function(element, container) { + if (element === container) { + return true; + } + while (element = element.parentNode) { + if (element === container) { + return true; + } + } + return false; + }; + + Dropzone.getElement = function(el, name) { + var element; + if (typeof el === "string") { + element = document.querySelector(el); + } else if (el.nodeType != null) { + element = el; + } + if (element == null) { + throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element."); + } + return element; + }; + + Dropzone.getElements = function(els, name) { + var e, el, elements, _i, _j, _len, _len1, _ref; + if (els instanceof Array) { + elements = []; + try { + for (_i = 0, _len = els.length; _i < _len; _i++) { + el = els[_i]; + elements.push(this.getElement(el, name)); + } + } catch (_error) { + e = _error; + elements = null; + } + } else if (typeof els === "string") { + elements = []; + _ref = document.querySelectorAll(els); + for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { + el = _ref[_j]; + elements.push(el); + } + } else if (els.nodeType != null) { + elements = [els]; + } + if (!((elements != null) && elements.length)) { + throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those."); + } + return elements; + }; + + Dropzone.confirm = function(question, accepted, rejected) { + if (window.confirm(question)) { + return accepted(); + } else if (rejected != null) { + return rejected(); + } + }; + + Dropzone.isValidFile = function(file, acceptedFiles) { + var baseMimeType, mimeType, validType, _i, _len; + if (!acceptedFiles) { + return true; + } + acceptedFiles = acceptedFiles.split(","); + mimeType = file.type; + baseMimeType = mimeType.replace(/\/.*$/, ""); + for (_i = 0, _len = acceptedFiles.length; _i < _len; _i++) { + validType = acceptedFiles[_i]; + validType = validType.trim(); + if (validType.charAt(0) === ".") { + if (file.name.indexOf(validType, file.name.length - validType.length) !== -1) { + return true; + } + } else if (/\/\*$/.test(validType)) { + if (baseMimeType === validType.replace(/\/.*$/, "")) { + return true; + } + } else { + if (mimeType === validType) { + return true; + } + } + } + return false; + }; + + if (typeof jQuery !== "undefined" && jQuery !== null) { + jQuery.fn.dropzone = function(options) { + return this.each(function() { + return new Dropzone(this, options); + }); + }; + } + + if (typeof module !== "undefined" && module !== null) { + module.exports = Dropzone; + } else { + window.Dropzone = Dropzone; + } + + Dropzone.ADDED = "added"; + + Dropzone.QUEUED = "queued"; + + Dropzone.ACCEPTED = Dropzone.QUEUED; + + Dropzone.UPLOADING = "uploading"; + + Dropzone.PROCESSING = Dropzone.UPLOADING; + + Dropzone.CANCELED = "canceled"; + + Dropzone.ERROR = "error"; + + Dropzone.SUCCESS = "success"; + + /* + # contentloaded.js + # + # Author: Diego Perini (diego.perini at gmail.com) + # Summary: cross-browser wrapper for DOMContentLoaded + # Updated: 20101020 + # License: MIT + # Version: 1.2 + # + # URL: + # http://javascript.nwbox.com/ContentLoaded/ + # http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE + */ + + + contentLoaded = function(win, fn) { + var add, doc, done, init, poll, pre, rem, root, top; + done = false; + top = true; + doc = win.document; + root = doc.documentElement; + add = (doc.addEventListener ? "addEventListener" : "attachEvent"); + rem = (doc.addEventListener ? "removeEventListener" : "detachEvent"); + pre = (doc.addEventListener ? "" : "on"); + init = function(e) { + if (e.type === "readystatechange" && doc.readyState !== "complete") { + return; + } + (e.type === "load" ? win : doc)[rem](pre + e.type, init, false); + if (!done && (done = true)) { + return fn.call(win, e.type || e); + } + }; + poll = function() { + var e; + try { + root.doScroll("left"); + } catch (_error) { + e = _error; + setTimeout(poll, 50); + return; + } + return init("poll"); + }; + if (doc.readyState !== "complete") { + if (doc.createEventObject && root.doScroll) { + try { + top = !win.frameElement; + } catch (_error) {} + if (top) { + poll(); + } + } + doc[add](pre + "DOMContentLoaded", init, false); + doc[add](pre + "readystatechange", init, false); + return win[add](pre + "load", init, false); + } + }; + + Dropzone._autoDiscoverFunction = function() { + if (Dropzone.autoDiscover) { + return Dropzone.discover(); + } + }; + + contentLoaded(window, Dropzone._autoDiscoverFunction); + + }).call(this); + + }); + require.alias("component-emitter/index.js", "dropzone/deps/emitter/index.js"); + require.alias("component-emitter/index.js", "emitter/index.js"); + if (typeof exports == "object") { + module.exports = require("dropzone"); + } else if (typeof define == "function" && define.amd) { + define(function(){ return require("dropzone"); }); + } else { + this["Dropzone"] = require("dropzone"); + }})(); \ No newline at end of file diff --git a/templates/admin/default/assets/js/image-upload.js b/templates/admin/default/assets/js/image-upload.js index 45e63ffbd..c4426e6de 100644 --- a/templates/admin/default/assets/js/image-upload.js +++ b/templates/admin/default/assets/js/image-upload.js @@ -1,28 +1,37 @@ -// Manage picture upload $(function($){ - + // Manage picture upload var pictureUploadManager = {}; - // Set selected image as preview - pictureUploadManager.onChangePreviewPicture = function() { - $('#images input:file').on('change', function () { - var $this = $(this); - if ($this.prop("files") && $this.prop("files")[0]) { - var reader = new FileReader(); - - reader.onload = function (e) { - $this.parent() - .find('img.preview') - .attr('src', e.target.result) - .width(150) - .height(200); - } - - reader.readAsDataURL($this.prop("files")[0]); - } - }); + var imageDropzone = new Dropzone("#images-dropzone"); + Dropzone.options.imageDropzone = { + uploadMultiple: false + }; + imageDropzone.on("success", function(file) { + $(".image-manager .dz-file-preview").remove(); + imageDropzone.removeFile(file); + pictureUploadManager.updateImageListAjax(); + }); + + // Update picture list via AJAX call + pictureUploadManager.updateImageListAjax = function() { + var $imageListArea = $(".image-manager .existing-image"); + $imageListArea.html('
'); + $.ajax({ + type: "POST", + url: imageListUrl, + statusCode: { + 404: function() { + $imageListArea.html( + imageListErrorMessage + ); + } + } + }).done(function(data) { + $imageListArea.html( + data + ); + }); }; - pictureUploadManager.onChangePreviewPicture(); // Remove image on click pictureUploadManager.onClickDeleteImage = function() { @@ -52,16 +61,4 @@ $(function($){ }); }; pictureUploadManager.onClickDeleteImage(); - - // Remove image on click - pictureUploadManager.clonePictureInputs = function() { - var $inputs = $(".image-manager .picture-input"); - if ($inputs.size == 1) { - console.log('1'); - $(".image-manager .picture-input").last().show(); - } else { - console.log('+d1'); - $(".image-manager .picture-input").last().clone().appendTo(".image-manager .pictures-input"); - } - } -}); \ No newline at end of file +}); diff --git a/templates/admin/default/category-edit.html b/templates/admin/default/category-edit.html index b315665b6..e9c3f72a1 100755 --- a/templates/admin/default/category-edit.html +++ b/templates/admin/default/category-edit.html @@ -256,7 +256,7 @@
- {include file='includes/image-upload-form.html' formName="thelia.admin.category.image.creation" formSuccessUrl={url path="/admin/categories/update?category_id=$category_id"} imageType='category' parentId=$category_id} + {include file='includes/image-upload-form.html' imageType='category' parentId=$category_id}
@@ -297,9 +297,14 @@ {/block} {block name="javascript-initialization"} -{javascripts file='assets/js/image-upload.js'} - -{/javascripts} + {javascripts file='assets/js/dropzone.js'} + + {/javascripts} + {javascripts file='assets/js/image-upload.js'} + + {/javascripts} + + + {/javascripts} +{/block} \ No newline at end of file diff --git a/templates/admin/default/includes/image-upload-form.html b/templates/admin/default/includes/image-upload-form.html index 64253c346..46c949841 100644 --- a/templates/admin/default/includes/image-upload-form.html +++ b/templates/admin/default/includes/image-upload-form.html @@ -1,80 +1,476 @@ +{* +A generic image upload form + +Parameters: + imageType = Image type (category, product, folder, content, module) + parentId = Image parent id, ex: category id + +*} +
-
{$imageMessage}
+
+
+ +
+
+
- {loop type="image" name="image_test" source="{$imageType}" source_id="{$parentId}" width="200" height="100" resize_mode="borders"} - - {/loop} + {include file='includes/image-upload-list-ajax.html'}
- {form name=$formName} -
-
flashMessage = {flashMessage key="imageMessage"}{$value}{/flashMessage}
- {form_hidden_fields form=$form} +{*{block name="javascript-initialization"}*} + {*{$smarty.block.parent}*} - {*{form_field form=$form field='locale'}*} - {**} - {*{/form_field}*} + {*{javascripts file='assets/js/image-upload.js'}*} + {**} + {*{/javascripts}*} + {*{javascripts file='assets/js/dropzone.js'}*} + {**} + {*{/javascripts}*} +{*{/block}*} - {form_field form=$form field='success_url'} - - {/form_field} + +{* +@todo refactor +see http://www.dropzonejs.com/ - {form_field form=$form field='pictures'} -
- {*$value={$value|var_dump}*} - {*$error={$error|var_dump}*} - {*$message={$message|var_dump}*} - {*img0={$value.0|var_dump}*} - {*img0={$value.0->getFile()}*} - {*img1={$value[1]->getFile()}*} -
- - {*{form_field form=$form field='pictures.0.title'}*} - {*$name={$name|var_dump}*} - - {*{/form_field}*} - {*{form_field form=$form field='pictures.0.file'}*} - {*$name={$name|var_dump}*} - - {*{/form_field}*} - Your image -
- {*
*} - {**} - {**} - {**} - {*Your image*} - {*
*} - {*
*} - {**} - {**} - {**} - {*Your image*} - {*
*} - {*
*} - {**} - {**} - {**} - {*Your image*} - {*
*} - {*
*} - {**} - {**} - {**} - {*Your image*} - {*
*} - {if $error}{$message}{/if} -
- {/form_field} +*} + \ No newline at end of file diff --git a/templates/admin/default/includes/image-upload-list-ajax.html b/templates/admin/default/includes/image-upload-list-ajax.html new file mode 100644 index 000000000..a61d1f08d --- /dev/null +++ b/templates/admin/default/includes/image-upload-list-ajax.html @@ -0,0 +1,23 @@ +{* + +A generic image upload form + +Parameters: + imageType = Image type (category, product, folder, content, module) + parentId = Image parent id, ex: category id + +*} + +{loop type="image" name="image" source="{$imageType}" source_id="{$parentId}" width="200" height="100" resize_mode="borders"} + +{/loop} + + diff --git a/web/test_to_remove/admin-stats.json b/web/test_to_remove/admin-stats.json old mode 100644 new mode 100755 From 22f3f49f799d0fd0c7bb53c4acd099952dea1e40 Mon Sep 17 00:00:00 2001 From: franck Date: Sun, 22 Sep 2013 22:14:39 +0200 Subject: [PATCH 11/43] Finished product multiple categories attachment --- core/lib/Thelia/Action/Attribute.php | 14 +- core/lib/Thelia/Action/AttributeAv.php | 14 +- core/lib/Thelia/Action/BaseAction.php | 27 + core/lib/Thelia/Action/Category.php | 14 +- core/lib/Thelia/Action/Currency.php | 15 +- core/lib/Thelia/Action/Feature.php | 14 +- core/lib/Thelia/Action/FeatureAv.php | 14 +- core/lib/Thelia/Action/Product.php | 91 +-- core/lib/Thelia/Action/Template.php | 25 +- .../Thelia/Config/Resources/routing/admin.xml | 17 +- .../Admin/AbstractCrudController.php | 34 ++ .../Controller/Admin/ProductController.php | 154 +++-- .../Controller/Admin/TemplateController.php | 36 +- .../Core/Event/ProductAddCategoryEvent.php | 48 ++ .../Thelia/Core/Event/ProductCreateEvent.php | 49 ++ .../Core/Event/ProductDeleteCategoryEvent.php | 50 ++ core/lib/Thelia/Core/Event/TheliaEvents.php | 18 +- .../Thelia/Core/Template/Loop/Accessory.php | 22 +- .../Core/Template/Loop/AssociatedContent.php | 26 +- .../Thelia/Core/Template/Loop/Attribute.php | 9 +- .../Thelia/Core/Template/Loop/Category.php | 19 + .../lib/Thelia/Core/Template/Loop/Feature.php | 9 +- core/lib/Thelia/Form/ProductCreationForm.php | 32 +- core/lib/Thelia/Model/Product.php | 21 +- .../Thelia/Model/ProductAssociatedContent.php | 11 + install/faker.php | 1 + install/insert.sql | 4 +- .../default/ajax/product-attributes-tab.html | 48 +- .../default/ajax/product-prices-tab.html | 75 +++ .../default/ajax/product-related-tab.html | 554 +++++++++++------- .../default/ajax/template-attribute-list.html | 2 +- .../default/ajax/template-feature-list.html | 2 +- templates/admin/default/categories.html | 60 +- .../default/includes/generic-js-dialog.html | 2 +- .../product-general-tab.html | 4 +- .../standard-description-form-fields.html | 4 +- templates/admin/default/product-edit.html | 8 +- 37 files changed, 1049 insertions(+), 498 deletions(-) create mode 100644 core/lib/Thelia/Core/Event/ProductAddCategoryEvent.php create mode 100644 core/lib/Thelia/Core/Event/ProductDeleteCategoryEvent.php create mode 100644 templates/admin/default/ajax/product-prices-tab.html rename templates/admin/default/{ajax => includes}/product-general-tab.html (97%) diff --git a/core/lib/Thelia/Action/Attribute.php b/core/lib/Thelia/Action/Attribute.php index 44c5968a4..12478e8a1 100644 --- a/core/lib/Thelia/Action/Attribute.php +++ b/core/lib/Thelia/Action/Attribute.php @@ -123,19 +123,7 @@ class Attribute extends BaseAction implements EventSubscriberInterface */ 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(); - } + return $this->genericUpdatePosition(AttributeQuery::create(), $event); } protected function doAddToAllTemplates(AttributeModel $attribute) diff --git a/core/lib/Thelia/Action/AttributeAv.php b/core/lib/Thelia/Action/AttributeAv.php index a6b442fa2..0a72739d1 100644 --- a/core/lib/Thelia/Action/AttributeAv.php +++ b/core/lib/Thelia/Action/AttributeAv.php @@ -112,19 +112,7 @@ class AttributeAv extends BaseAction implements EventSubscriberInterface */ public function updatePosition(UpdatePositionEvent $event) { - if (null !== $attribute = AttributeAvQuery::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(); - } + return $this->genericUpdatePosition(AttributeAvQuery::create(), $event); } diff --git a/core/lib/Thelia/Action/BaseAction.php b/core/lib/Thelia/Action/BaseAction.php index 56565ddc6..7f501db83 100755 --- a/core/lib/Thelia/Action/BaseAction.php +++ b/core/lib/Thelia/Action/BaseAction.php @@ -23,6 +23,9 @@ namespace Thelia\Action; use Symfony\Component\DependencyInjection\ContainerInterface; +use Propel\Runtime\ActiveQuery\PropelQuery; +use Propel\Runtime\ActiveQuery\ModelCriteria; +use Thelia\Core\Event\UpdatePositionEvent; class BaseAction { @@ -45,4 +48,28 @@ class BaseAction { return $this->container->get('event_dispatcher'); } + + + /** + * Changes object position, selecting absolute ou relative change. + * + * @param $query the query to retrieve the object to move + * @param UpdatePositionEvent $event + */ + protected function genericUpdatePosition(ModelCriteria $query, UpdatePositionEvent $event) + { + if (null !== $object = $query->findPk($event->getObjectId())) { + + $object->setDispatcher($this->getDispatcher()); + + $mode = $event->getMode(); + + if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE) + return $object->changeAbsolutePosition($event->getPosition()); + else if ($mode == UpdatePositionEvent::POSITION_UP) + return $object->movePositionUp(); + else if ($mode == UpdatePositionEvent::POSITION_DOWN) + return $object->movePositionDown(); + } + } } diff --git a/core/lib/Thelia/Action/Category.php b/core/lib/Thelia/Action/Category.php index 25a94711f..8429a7c4e 100755 --- a/core/lib/Thelia/Action/Category.php +++ b/core/lib/Thelia/Action/Category.php @@ -136,19 +136,7 @@ class Category extends BaseAction implements EventSubscriberInterface */ public function updatePosition(UpdatePositionEvent $event) { - if (null !== $category = CategoryQuery::create()->findPk($event->getObjectId())) { - - $category->setDispatcher($this->getDispatcher()); - - $mode = $event->getMode(); - - if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE) - return $category->changeAbsolutePosition($event->getPosition()); - else if ($mode == UpdatePositionEvent::POSITION_UP) - return $category->movePositionUp(); - else if ($mode == UpdatePositionEvent::POSITION_DOWN) - return $category->movePositionDown(); - } + return $this->genericUpdatePosition(CategoryQuery::create(), $event); } public function addContent(CategoryAddContentEvent $event) { diff --git a/core/lib/Thelia/Action/Currency.php b/core/lib/Thelia/Action/Currency.php index 946fee375..3c428683b 100644 --- a/core/lib/Thelia/Action/Currency.php +++ b/core/lib/Thelia/Action/Currency.php @@ -166,20 +166,7 @@ class Currency extends BaseAction implements EventSubscriberInterface */ public function updatePosition(UpdatePositionEvent $event) { - if (null !== $currency = CurrencyQuery::create()->findPk($event->getObjectId())) { - - $currency->setDispatcher($this->getDispatcher()); - - $mode = $event->getMode(); - echo "loaded $mode !"; - - if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE) - return $currency->changeAbsolutePosition($event->getPosition()); - else if ($mode == UpdatePositionEvent::POSITION_UP) - return $currency->movePositionUp(); - else if ($mode == UpdatePositionEvent::POSITION_DOWN) - return $currency->movePositionDown(); - } + return $this->genericUpdatePosition(CurrencyQuery::create(), $event); } /** diff --git a/core/lib/Thelia/Action/Feature.php b/core/lib/Thelia/Action/Feature.php index a746ce4e2..01799510c 100644 --- a/core/lib/Thelia/Action/Feature.php +++ b/core/lib/Thelia/Action/Feature.php @@ -123,19 +123,7 @@ class Feature extends BaseAction implements EventSubscriberInterface */ public function updatePosition(UpdatePositionEvent $event) { - if (null !== $feature = FeatureQuery::create()->findPk($event->getObjectId())) { - - $feature->setDispatcher($this->getDispatcher()); - - $mode = $event->getMode(); - - if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE) - return $feature->changeAbsolutePosition($event->getPosition()); - else if ($mode == UpdatePositionEvent::POSITION_UP) - return $feature->movePositionUp(); - else if ($mode == UpdatePositionEvent::POSITION_DOWN) - return $feature->movePositionDown(); - } + return $this->genericUpdatePosition(FeatureQuery::create(), $event); } protected function doAddToAllTemplates(FeatureModel $feature) diff --git a/core/lib/Thelia/Action/FeatureAv.php b/core/lib/Thelia/Action/FeatureAv.php index 2bd117b4b..25f9ae5f2 100644 --- a/core/lib/Thelia/Action/FeatureAv.php +++ b/core/lib/Thelia/Action/FeatureAv.php @@ -112,19 +112,7 @@ class FeatureAv extends BaseAction implements EventSubscriberInterface */ public function updatePosition(UpdatePositionEvent $event) { - if (null !== $feature = FeatureAvQuery::create()->findPk($event->getObjectId())) { - - $feature->setDispatcher($this->getDispatcher()); - - $mode = $event->getMode(); - - if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE) - return $feature->changeAbsolutePosition($event->getPosition()); - else if ($mode == UpdatePositionEvent::POSITION_UP) - return $feature->movePositionUp(); - else if ($mode == UpdatePositionEvent::POSITION_DOWN) - return $feature->movePositionDown(); - } + return $this->genericUpdatePosition(FeatureAvQuery::create(), $event); } diff --git a/core/lib/Thelia/Action/Product.php b/core/lib/Thelia/Action/Product.php index 47576c8cc..97c3dbdd7 100644 --- a/core/lib/Thelia/Action/Product.php +++ b/core/lib/Thelia/Action/Product.php @@ -58,6 +58,9 @@ use Thelia\Core\Event\ProductSetTemplateEvent; use Thelia\Model\AttributeCombinationQuery; use Thelia\Core\Template\Loop\ProductSaleElements; use Thelia\Model\ProductSaleElementsQuery; +use Propel\Runtime\ActiveQuery\PropelQuery; +use Thelia\Core\Event\ProductDeleteCategoryEvent; +use Thelia\Core\Event\ProductAddCategoryEvent; class Product extends BaseAction implements EventSubscriberInterface { @@ -81,7 +84,15 @@ class Product extends BaseAction implements EventSubscriberInterface // Set the default tax rule to this product ->setTaxRule(TaxRuleQuery::create()->findOneByIsDefault(true)) - ->create($event->getDefaultCategory()) + //public function create($defaultCategoryId, $basePrice, $priceCurrencyId, $taxRuleId, $baseWeight) { + + ->create( + $event->getDefaultCategory(), + $event->getBasePrice(), + $event->getCurrencyId(), + $event->getTaxRuleId(), + $event->getBaseWeight() + ); ; $event->setProduct($product); @@ -94,8 +105,6 @@ class Product extends BaseAction implements EventSubscriberInterface */ public function update(ProductUpdateEvent $event) { - $search = ProductQuery::create(); - if (null !== $product = ProductQuery::create()->findPk($event->getProductId())) { $product @@ -162,19 +171,7 @@ class Product extends BaseAction implements EventSubscriberInterface */ public function updatePosition(UpdatePositionEvent $event) { - if (null !== $product = ProductQuery::create()->findPk($event->getObjectId())) { - - $product->setDispatcher($this->getDispatcher()); - - $mode = $event->getMode(); - - if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE) - return $product->changeAbsolutePosition($event->getPosition()); - else if ($mode == UpdatePositionEvent::POSITION_UP) - return $product->movePositionUp(); - else if ($mode == UpdatePositionEvent::POSITION_DOWN) - return $product->movePositionDown(); - } + return $this->genericUpdatePosition(ProductQuery::create(), $event); } public function addContent(ProductAddContentEvent $event) { @@ -208,6 +205,34 @@ class Product extends BaseAction implements EventSubscriberInterface ; } + public function addCategory(ProductAddCategoryEvent $event) { + + if (ProductCategoryQuery::create() + ->filterByProduct($event->getProduct()) + ->filterByCategoryId($event->getCategoryId()) + ->count() <= 0) { + + $productCategory = new ProductCategory(); + + $productCategory + ->setProduct($event->getProduct()) + ->setCategoryId($event->getCategoryId()) + ->setDefaultCategory(false) + ->save() + ; + } + } + + public function removeCategory(ProductDeleteCategoryEvent $event) { + + $productCategory = ProductCategoryQuery::create() + ->filterByProduct($event->getProduct()) + ->filterByCategoryId($event->getCategoryId()) + ->findOne(); + + if ($productCategory != null) $productCategory->delete(); + } + public function addAccessory(ProductAddAccessoryEvent $event) { if (AccessoryQuery::create() @@ -259,25 +284,23 @@ class Product extends BaseAction implements EventSubscriberInterface } /** - * Changes position, selecting absolute ou relative change. + * Changes accessry position, selecting absolute ou relative change. * * @param ProductChangePositionEvent $event */ public function updateAccessoryPosition(UpdatePositionEvent $event) { - if (null !== $accessory = AccessoryQuery::create()->findPk($event->getObjectId())) { + return $this->genericUpdatePosition(AccessoryQuery::create(), $event); + } - $accessory->setDispatcher($this->getDispatcher()); - - $mode = $event->getMode(); - - if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE) - return $accessory->changeAbsolutePosition($event->getPosition()); - else if ($mode == UpdatePositionEvent::POSITION_UP) - return $accessory->movePositionUp(); - else if ($mode == UpdatePositionEvent::POSITION_DOWN) - return $accessory->movePositionDown(); - } + /** + * Changes position, selecting absolute ou relative change. + * + * @param ProductChangePositionEvent $event + */ + public function updateContentPosition(UpdatePositionEvent $event) + { + return $this->genericUpdatePosition(ProductAssociatedContentQuery::create(), $event); } public function updateFeatureProductValue(FeatureProductUpdateEvent $event) { @@ -299,10 +322,8 @@ class Product extends BaseAction implements EventSubscriberInterface } $featureProduct = $featureProductQuery->findOne(); -echo "
create or update: f=".$event->getFeatureId().", p=".$event->getProductId(); if ($featureProduct == null) { -echo " Create !"; $featureProduct = new FeatureProduct(); $featureProduct @@ -313,7 +334,6 @@ echo " Create !"; ; } - else echo " Update !"; if ($event->getIsTextValue() == true) { $featureProduct->setFreeTextValue($event->getFeatureValue()); @@ -321,7 +341,6 @@ echo " Create !"; else { $featureProduct->setFeatureAvId($event->getFeatureValue()); } -echo "value=".$event->getFeatureValue(); $featureProduct->save(); @@ -335,8 +354,6 @@ echo "value=".$event->getFeatureValue(); ->filterByFeatureId($event->getFeatureId()) ->delete() ; - - echo "
Delete p=".$event->getProductId().", f=".$event->getFeatureId(); } /** @@ -355,10 +372,14 @@ echo "value=".$event->getFeatureValue(); TheliaEvents::PRODUCT_ADD_CONTENT => array("addContent", 128), TheliaEvents::PRODUCT_REMOVE_CONTENT => array("removeContent", 128), TheliaEvents::PRODUCT_UPDATE_ACCESSORY_POSITION => array("updateAccessoryPosition", 128), + TheliaEvents::PRODUCT_UPDATE_CONTENT_POSITION => array("updateContentPosition", 128), TheliaEvents::PRODUCT_ADD_ACCESSORY => array("addAccessory", 128), TheliaEvents::PRODUCT_REMOVE_ACCESSORY => array("removeAccessory", 128), + TheliaEvents::PRODUCT_ADD_CATEGORY => array("addCategory", 128), + TheliaEvents::PRODUCT_REMOVE_CATEGORY => array("removeCategory", 128), + TheliaEvents::PRODUCT_SET_TEMPLATE => array("setProductTemplate", 128), TheliaEvents::PRODUCT_FEATURE_UPDATE_VALUE => array("updateFeatureProductValue", 128), diff --git a/core/lib/Thelia/Action/Template.php b/core/lib/Thelia/Action/Template.php index 101332a75..47d5d7a4d 100644 --- a/core/lib/Thelia/Action/Template.php +++ b/core/lib/Thelia/Action/Template.php @@ -142,9 +142,7 @@ class Template extends BaseAction implements EventSubscriberInterface */ public function updateAttributePosition(UpdatePositionEvent $event) { - $attributeTemplate = AttributeTemplateQuery::create()->findPk($event->getObjectId()); - - $this->updatePosition($attributeTemplate, $event); + return $this->genericUpdatePosition(AttributeTemplateQuery::create(), $event); } /** @@ -154,26 +152,7 @@ class Template extends BaseAction implements EventSubscriberInterface */ public function updateFeaturePosition(UpdatePositionEvent $event) { - $featureTemplate = FeatureTemplateQuery::create()->findPk($event->getObjectId()); - - $this->updatePosition($featureTemplate, $event); - } - - protected function updatePosition($object, UpdatePositionEvent $event) - { - if (null !== $object) { - - $object->setDispatcher($this->getDispatcher()); - - $mode = $event->getMode(); - - if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE) - $object->changeAbsolutePosition($event->getPosition()); - else if ($mode == UpdatePositionEvent::POSITION_UP) - $object->movePositionUp(); - else if ($mode == UpdatePositionEvent::POSITION_DOWN) - $object->movePositionDown(); - } + return $this->genericUpdatePosition(FeatureTemplateQuery::create(), $event); } public function deleteAttribute(TemplateDeleteAttributeEvent $event) { diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 7eacde1cd..5b40ff65a 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -155,13 +155,24 @@ Thelia\Controller\Admin\ProductController::loadGeneralAjaxTabAction - + Thelia\Controller\Admin\ProductController::loadRelatedAjaxTabAction + + + + Thelia\Controller\Admin\ProductController::addAdditionalCategoryAction + + + + Thelia\Controller\Admin\ProductController::deleteAdditionalCategoryAction + + + Thelia\Controller\Admin\ProductController::addRelatedContentAction @@ -175,6 +186,10 @@ xml|json + + Thelia\Controller\Admin\ProductController::updateContentPositionAction + + diff --git a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php index 67d1e8a5b..2bac27101 100644 --- a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php +++ b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php @@ -446,6 +446,8 @@ abstract class AbstractCrudController extends BaseAdminController /** * Update object position (only for objects whichsupport that) + * + * FIXME: integrate with genericUpdatePositionAction */ public function updatePositionAction() { @@ -483,6 +485,38 @@ abstract class AbstractCrudController extends BaseAdminController } } + protected function genericUpdatePositionAction($object, $eventName, $doFinalRedirect = true) { + + // Check current user authorization + if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response; + + if ($object != null) { + + 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 = new UpdatePositionEvent($object->getId(), $mode, $position); + + $this->dispatch($eventName, $event); + } + catch (\Exception $ex) { + // Any error + return $this->errorPage($ex); + } + } + + if ($doFinalRedirect) $this->redirectToEditionTemplate(); + } + /** * Online status toggle (only for object which support it) */ diff --git a/core/lib/Thelia/Controller/Admin/ProductController.php b/core/lib/Thelia/Controller/Admin/ProductController.php index 12ad3510d..2b1cc9550 100644 --- a/core/lib/Thelia/Controller/Admin/ProductController.php +++ b/core/lib/Thelia/Controller/Admin/ProductController.php @@ -48,6 +48,9 @@ use Thelia\Model\FeatureQuery; use Thelia\Core\Event\FeatureProductDeleteEvent; use Thelia\Model\FeatureTemplateQuery; use Thelia\Core\Event\ProductSetTemplateEvent; +use Thelia\Model\Base\ProductSaleElementsQuery; +use Thelia\Core\Event\ProductAddCategoryEvent; +use Thelia\Core\Event\ProductDeleteCategoryEvent; /** * Manages products @@ -77,33 +80,6 @@ class ProductController extends AbstractCrudController ); } - /** - * General ajax tab loading - */ - public function loadGeneralAjaxTabAction() { - - // Load the object - $object = $this->getExistingObject(); - - 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); - - return $this->render( - 'ajax/product-general-tab', - array( - 'product_id' => $this->getRequest()->get('product_id', 0), - ) - ); - } - - $this->redirectToListTemplate(); - } - /** * Attributes ajax tab loading */ @@ -125,9 +101,10 @@ class ProductController extends AbstractCrudController return $this->render( 'ajax/product-related-tab', array( - 'product_id' => $this->getRequest()->get('product_id', 0), - 'folder_id' => $this->getRequest()->get('folder_id', 0), - 'accessory_category_id'=> $this->getRequest()->get('accessory_category_id', 0) + 'product_id' => $this->getRequest()->get('product_id', 0), + 'folder_id' => $this->getRequest()->get('folder_id', 0), + 'accessory_category_id' => $this->getRequest()->get('accessory_category_id', 0) + ) ); } @@ -152,6 +129,10 @@ class ProductController extends AbstractCrudController ->setLocale($formData['locale']) ->setDefaultCategory($formData['default_category']) ->setVisible($formData['visible']) + ->setBasePrice($formData['price']) + ->setBaseWeight($formData['weight']) + ->setCurrencyId($formData['currency']) + ->setTaxRuleId($formData['tax_rule']) ; return $createEvent; @@ -171,6 +152,10 @@ class ProductController extends AbstractCrudController ->setVisible($formData['visible']) ->setUrl($formData['url']) ->setDefaultCategory($formData['default_category']) + ->setBasePrice($formData['price']) + ->setBaseWeight($formData['weight']) + ->setCurrencyId($formData['currency']) + ->setTaxRuleId($formData['tax_rule']) ; return $changeEvent; @@ -197,6 +182,11 @@ class ProductController extends AbstractCrudController protected function hydrateObjectForm($object) { + // Get the default produc sales element + $salesElement = ProductSaleElementsQuery::create()->filterByProduct($object)->filterByIsDefault(true)->findOne(); + +// $prices = $salesElement->getProductPrices(); + // Prepare the data that will hydrate the form $data = array( 'id' => $object->getId(), @@ -209,6 +199,8 @@ class ProductController extends AbstractCrudController 'visible' => $object->getVisible(), 'url' => $object->getRewrittenUrl($this->getCurrentEditionLocale()), 'default_category' => $object->getDefaultCategoryId() + + // A terminer pour les prix ); // Setup the object form @@ -240,10 +232,10 @@ class ProductController extends AbstractCrudController protected function getEditionArguments() { return array( - 'category_id' => $this->getCategoryId(), - 'product_id' => $this->getRequest()->get('product_id', 0), - 'folder_id' => $this->getRequest()->get('folder_id', 0), - 'accessory_category_id'=> $this->getRequest()->get('accessory_category_id', 0), + 'category_id' => $this->getCategoryId(), + 'product_id' => $this->getRequest()->get('product_id', 0), + 'folder_id' => $this->getRequest()->get('folder_id', 0), + 'accessory_category_id' => $this->getRequest()->get('accessory_category_id', 0), 'current_tab' => $this->getRequest()->get('current_tab', 'general') ); } @@ -478,7 +470,6 @@ class ProductController extends AbstractCrudController public function deleteAccessoryAction() { - // Check current user authorization if (null !== $response = $this->checkAuth("admin.products.update")) return $response; @@ -508,33 +499,26 @@ class ProductController extends AbstractCrudController */ public function updateAccessoryPositionAction() { - // Check current user authorization - if (null !== $response = $this->checkAuth('admin.products.update')) return $response; + $accessory = AccessoryQuery::create()->findPk($this->getRequest()->get('accessory_id', null)); - 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 = new UpdatePositionEvent($this->getRequest()->get('accessory_id', null), $mode, $position); - - $this->dispatch(TheliaEvents::PRODUCT_UPDATE_ACCESSORY_POSITION, $event); - } - catch (\Exception $ex) { - // Any error - return $this->errorPage($ex); - } - - $this->redirectToEditionTemplate(); + return $this->genericUpdatePositionAction( + $accessory, + TheliaEvents::PRODUCT_UPDATE_ACCESSORY_POSITION + ); } + /** + * Update related content position + */ + public function updateContentPositionAction() + { + $content = ProductAssociatedContentQuery::create()->findPk($this->getRequest()->get('content_id', null)); + + return $this->genericUpdatePositionAction( + $content, + TheliaEvents::PRODUCT_UPDATE_CONTENT_POSITION + ); + } /** * Change product template for a given product. @@ -636,4 +620,56 @@ class ProductController extends AbstractCrudController // Redirect to the category/product list $this->redirectToListTemplate(); } + + public function addAdditionalCategoryAction() { + + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.products.update")) return $response; + + $category_id = intval($this->getRequest()->get('additional_category_id')); + + if ($category_id > 0) { + + $event = new ProductAddCategoryEvent( + $this->getExistingObject(), + $category_id + ); + + try { + $this->dispatch(TheliaEvents::PRODUCT_ADD_CATEGORY, $event); + } + catch (\Exception $ex) { + // Any error + return $this->errorPage($ex); + } + } + + $this->redirectToEditionTemplate(); + } + + public function deleteAdditionalCategoryAction() { + + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.products.update")) return $response; + + $category_id = intval($this->getRequest()->get('additional_category_id')); + + if ($category_id > 0) { + + $event = new ProductDeleteCategoryEvent( + $this->getExistingObject(), + $category_id + ); + + try { + $this->dispatch(TheliaEvents::PRODUCT_REMOVE_CATEGORY, $event); + } + catch (\Exception $ex) { + // Any error + return $this->errorPage($ex); + } + } + + $this->redirectToEditionTemplate(); + } } diff --git a/core/lib/Thelia/Controller/Admin/TemplateController.php b/core/lib/Thelia/Controller/Admin/TemplateController.php index b8e9c0082..fb32e4231 100644 --- a/core/lib/Thelia/Controller/Admin/TemplateController.php +++ b/core/lib/Thelia/Controller/Admin/TemplateController.php @@ -266,7 +266,7 @@ class TemplateController extends AbstractCrudController ->findOne() ; - return $this->updatePosition( + return $this->genericUpdatePositionAction( $attributeTemplate, TheliaEvents::TEMPLATE_CHANGE_ATTRIBUTE_POSITION ); @@ -325,41 +325,9 @@ class TemplateController extends AbstractCrudController ->findOne() ; - return $this->updatePosition( + return $this->genericUpdatePositionAction( $featureTemplate, TheliaEvents::TEMPLATE_CHANGE_FEATURE_POSITION ); } - - protected function updatePosition($object, $eventName) { - - // Check current user authorization - if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response; - - if ($object != null) { - - 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 = new UpdatePositionEvent($object->getId(), $mode, $position); - - $this->dispatch($eventName, $event); - } - catch (\Exception $ex) { - // Any error - return $this->errorPage($ex); - } - } - - $this->redirectToEditionTemplate(); - } } \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/ProductAddCategoryEvent.php b/core/lib/Thelia/Core/Event/ProductAddCategoryEvent.php new file mode 100644 index 000000000..215b61f99 --- /dev/null +++ b/core/lib/Thelia/Core/Event/ProductAddCategoryEvent.php @@ -0,0 +1,48 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +use Thelia\Model\Product; + +class ProductAddCategoryEvent extends ProductEvent +{ + protected $category_id; + + public function __construct(Product $product, $category_id) + { + parent::__construct($product); + + $this->category_id = $category_id; + } + + public function getCategoryId() + { + return $this->category_id; + } + + public function setCategoryId($category_id) + { + $this->category_id = $category_id; + } +} diff --git a/core/lib/Thelia/Core/Event/ProductCreateEvent.php b/core/lib/Thelia/Core/Event/ProductCreateEvent.php index d2d30a11a..012d29793 100644 --- a/core/lib/Thelia/Core/Event/ProductCreateEvent.php +++ b/core/lib/Thelia/Core/Event/ProductCreateEvent.php @@ -31,6 +31,11 @@ class ProductCreateEvent extends ProductEvent protected $default_category; protected $visible; + protected $basePrice; + protected $baseWeight; + protected $taxRuleId; + protected $currencyId; + public function getRef() { return $this->ref; @@ -85,4 +90,48 @@ class ProductCreateEvent extends ProductEvent $this->visible = $visible; return $this; } + + public function getBasePrice() + { + return $this->basePrice; + } + + public function setBasePrice($basePrice) + { + $this->basePrice = $basePrice; + return $this; + } + + public function getBaseWeight() + { + return $this->baseWeight; + } + + public function setBaseWeight($baseWeight) + { + $this->baseWeight = $baseWeight; + return $this; + } + + public function getTaxRuleId() + { + return $this->taxRuleId; + } + + public function setTaxRuleId($taxRuleId) + { + $this->taxRuleId = $taxRuleId; + return $this; + } + + public function getCurrencyId() + { + return $this->currencyId; + } + + public function setCurrencyId($currencyId) + { + $this->currencyId = $currencyId; + return $this; + } } diff --git a/core/lib/Thelia/Core/Event/ProductDeleteCategoryEvent.php b/core/lib/Thelia/Core/Event/ProductDeleteCategoryEvent.php new file mode 100644 index 000000000..4fcfeee92 --- /dev/null +++ b/core/lib/Thelia/Core/Event/ProductDeleteCategoryEvent.php @@ -0,0 +1,50 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; +use Thelia\Model\Product; + +class ProductDeleteCategoryEvent extends ProductEvent +{ + protected $category_id; + + public function __construct(Product $product, $category_id) + { + parent::__construct($product); + + $this->category_id = $category_id; + } + + public function getCategoryId() + { + return $this->category_id; + } + + public function setCategoryId($category_id) + { + $this->category_id = $category_id; + + return $this; + } + +} diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 31a1d4730..767800733 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -184,17 +184,21 @@ final class TheliaEvents const PRODUCT_TOGGLE_VISIBILITY = "action.toggleProductVisibility"; const PRODUCT_UPDATE_POSITION = "action.updateProductPosition"; - const PRODUCT_ADD_CONTENT = "action.productAddContent"; - const PRODUCT_REMOVE_CONTENT = "action.productRemoveContent"; + const PRODUCT_ADD_CONTENT = "action.productAddContent"; + const PRODUCT_REMOVE_CONTENT = "action.productRemoveContent"; + const PRODUCT_UPDATE_CONTENT_POSITION = "action.updateProductContentPosition"; const PRODUCT_SET_TEMPLATE = "action.productSetTemplate"; - const PRODUCT_ADD_ACCESSORY = "action.productAddAccessory"; - const PRODUCT_REMOVE_ACCESSORY = "action.productRemoveAccessory"; - const PRODUCT_UPDATE_ACCESSORY_POSITION = "action.updateProductPosition"; + const PRODUCT_ADD_ACCESSORY = "action.productAddProductAccessory"; + const PRODUCT_REMOVE_ACCESSORY = "action.productRemoveProductAccessory"; + const PRODUCT_UPDATE_ACCESSORY_POSITION = "action.updateProductAccessoryPosition"; - const PRODUCT_FEATURE_UPDATE_VALUE = "action.after_updateProductFeatureValue"; - const PRODUCT_FEATURE_DELETE_VALUE = "action.after_deleteProductFeatureValue"; + const PRODUCT_FEATURE_UPDATE_VALUE = "action.updateProductFeatureValue"; + const PRODUCT_FEATURE_DELETE_VALUE = "action.deleteProductFeatureValue"; + + const PRODUCT_ADD_CATEGORY = "action.addProductCategory"; + const PRODUCT_REMOVE_CATEGORY = "action.deleteProductCategory"; const BEFORE_CREATEPRODUCT = "action.before_createproduct"; const AFTER_CREATEPRODUCT = "action.after_createproduct"; diff --git a/core/lib/Thelia/Core/Template/Loop/Accessory.php b/core/lib/Thelia/Core/Template/Loop/Accessory.php index 6dc269b62..34d674c10 100755 --- a/core/lib/Thelia/Core/Template/Loop/Accessory.php +++ b/core/lib/Thelia/Core/Template/Loop/Accessory.php @@ -74,6 +74,7 @@ class Accessory extends Product $search = AccessoryQuery::create(); $product = $this->getProduct(); + $search->filterByProductId($product, Criteria::IN); $order = $this->getOrder(); @@ -93,10 +94,16 @@ class Accessory extends Product $accessories = $this->search($search); $accessoryIdList = array(0); - $accessoryPosition = array(); + $accessoryPosition = $accessoryId = array(); + foreach ($accessories as $accessory) { - array_push($accessoryIdList, $accessory->getAccessory()); - $accessoryPosition[$accessory->getAccessory()] = $accessory->getPosition(); + + $accessoryProductId = $accessory->getAccessory(); + + array_push($accessoryIdList, $accessoryProductId); + + $accessoryPosition[$accessoryProductId] = $accessory->getPosition(); + $accessoryId[$accessoryProductId] = $accessory->getId(); } $receivedIdList = $this->getId(); @@ -111,12 +118,15 @@ class Accessory extends Product $loopResult = parent::exec($pagination); foreach($loopResult as $loopResultRow) { + + $accessoryProductId = $loopResultRow->get('ID'); + $loopResultRow - ->set("POSITION" , $accessoryPosition[$loopResultRow->get('ID')]) - ; + ->set("ID" , $accessoryId[$accessoryProductId]) + ->set("POSITION", $accessoryPosition[$accessoryProductId]) + ; } return $loopResult; } - } diff --git a/core/lib/Thelia/Core/Template/Loop/AssociatedContent.php b/core/lib/Thelia/Core/Template/Loop/AssociatedContent.php index 20fe5cb1e..78794b715 100755 --- a/core/lib/Thelia/Core/Template/Loop/AssociatedContent.php +++ b/core/lib/Thelia/Core/Template/Loop/AssociatedContent.php @@ -135,8 +135,17 @@ class AssociatedContent extends Content $associatedContents = $this->search($search); $associatedContentIdList = array(0); + + $contentIdList = array(0); + $contentPosition = $contentId = array(); + foreach ($associatedContents as $associatedContent) { - array_push($associatedContentIdList, $associatedContent->getContentId()); + + $associatedContentId = $associatedContent->getContentId(); + + array_push($associatedContentIdList, $associatedContentId); + $contentPosition[$associatedContentId] = $associatedContent->getPosition(); + $contentId[$associatedContentId] = $associatedContent->getId(); } $receivedIdList = $this->getId(); @@ -148,7 +157,18 @@ class AssociatedContent extends Content $this->args->get('id')->setValue( implode(',', array_intersect($receivedIdList, $associatedContentIdList)) ); } - return parent::exec($pagination); - } + $loopResult = parent::exec($pagination); + foreach($loopResult as $loopResultRow) { + + $relatedContentId = $loopResultRow->get('ID'); + + $loopResultRow + ->set("ID" , $contentId[$relatedContentId]) + ->set("POSITION", $contentPosition[$relatedContentId]) + ; + } + + return $loopResult; + } } diff --git a/core/lib/Thelia/Core/Template/Loop/Attribute.php b/core/lib/Thelia/Core/Template/Loop/Attribute.php index cb4a1cfdf..9a9aa6ff3 100755 --- a/core/lib/Thelia/Core/Template/Loop/Attribute.php +++ b/core/lib/Thelia/Core/Template/Loop/Attribute.php @@ -121,12 +121,15 @@ class Attribute extends BaseI18nLoop // Create template array if ($template == null) $template = array(); - foreach($products as $product) - $template[] = $product->getTemplateId(); + foreach($products as $product) { + $tpl_id = $product->getTemplateId(); + + if (! is_null($tpl_id)) $template[] = $tpl_id; + } } } - if (null !== $template) { + if (! empty($template)) { // Join with feature_template table to get position $search diff --git a/core/lib/Thelia/Core/Template/Loop/Category.php b/core/lib/Thelia/Core/Template/Loop/Category.php index 7a0bac76d..9c9ddab7d 100755 --- a/core/lib/Thelia/Core/Template/Loop/Category.php +++ b/core/lib/Thelia/Core/Template/Loop/Category.php @@ -35,6 +35,7 @@ use Thelia\Model\CategoryQuery; use Thelia\Type\TypeCollection; use Thelia\Type; use Thelia\Type\BooleanOrBothType; +use Thelia\Model\ProductQuery; /** * @@ -73,6 +74,8 @@ class Category extends BaseI18nLoop return new ArgumentCollection( Argument::createIntListTypeArgument('id'), Argument::createIntTypeArgument('parent'), + Argument::createIntTypeArgument('product'), + Argument::createIntTypeArgument('exclude_product'), Argument::createBooleanTypeArgument('current'), Argument::createBooleanTypeArgument('not_empty', 0), Argument::createBooleanOrBothTypeArgument('visible', 1), @@ -128,6 +131,22 @@ class Category extends BaseI18nLoop if ($this->getVisible() != BooleanOrBothType::ANY) $search->filterByVisible($this->getVisible() ? 1 : 0); + $product = $this->getProduct(); + + if ($product != null) { + $obj = ProductQuery::create()->findPk($product); + + if ($obj != null) $search->filterByProduct($obj, Criteria::IN); + } + + $exclude_product = $this->getExclude_product(); + + if ($exclude_product != null) { + $obj = ProductQuery::create()->findPk($exclude_product); + + if ($obj != null) $search->filterByProduct($obj, Criteria::NOT_IN); + } + $orders = $this->getOrder(); foreach ($orders as $order) { diff --git a/core/lib/Thelia/Core/Template/Loop/Feature.php b/core/lib/Thelia/Core/Template/Loop/Feature.php index c8fb2b8f1..f542b2e8d 100755 --- a/core/lib/Thelia/Core/Template/Loop/Feature.php +++ b/core/lib/Thelia/Core/Template/Loop/Feature.php @@ -124,12 +124,15 @@ class Feature extends BaseI18nLoop // Create template array if ($template == null) $template = array(); - foreach($products as $product) - $template[] = $product->getTemplateId(); + foreach($products as $product) { + $tpl_id = $product->getTemplateId(); + + if (! is_null($tpl_id)) $template[] = $tpl_id; + } } } - if (null !== $template) { + if (! empty($template)) { // Join with feature_template table to get position $search diff --git a/core/lib/Thelia/Form/ProductCreationForm.php b/core/lib/Thelia/Form/ProductCreationForm.php index 8050dcff9..82208981e 100644 --- a/core/lib/Thelia/Form/ProductCreationForm.php +++ b/core/lib/Thelia/Form/ProductCreationForm.php @@ -47,23 +47,43 @@ class ProductCreationForm extends BaseForm "label_attr" => array("for" => "ref") )) ->add("title", "text", array( - // "constraints" => array(new NotBlank()), + "constraints" => array(new NotBlank()), "label" => "Product title *", "label_attr" => array("for" => "title") )) ->add("default_category", "integer", array( - // "constraints" => array(new NotBlank()), - "label" => Translator::getInstance()->trans("Default product category."), + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Default product category *"), "label_attr" => array("for" => "default_category_field") )) ->add("locale", "text", array( - //"constraints" => array(new NotBlank()) + "constraints" => array(new NotBlank()) )) ->add("visible", "integer", array( - "label" => Translator::getInstance()->trans("This product is online."), + "label" => Translator::getInstance()->trans("This product is online"), "label_attr" => array("for" => "visible_field") )) - ; + ->add("price", "number", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Product base price excluding taxes *"), + "label_attr" => array("for" => "price_field") + )) + ->add("currency", "integer", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Price currency *"), + "label_attr" => array("for" => "currency_field") + )) + ->add("tax_rule", "integer", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Tax rule for this product *"), + "label_attr" => array("for" => "tax_rule_field") + )) + ->add("weight", "number", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Weight *"), + "label_attr" => array("for" => "weight_field") + )) + ; } public function checkDuplicateRef($value, ExecutionContextInterface $context) diff --git a/core/lib/Thelia/Model/Product.php b/core/lib/Thelia/Model/Product.php index 09a9b75db..3070e1915 100755 --- a/core/lib/Thelia/Model/Product.php +++ b/core/lib/Thelia/Model/Product.php @@ -98,7 +98,8 @@ class Product extends BaseProduct ->filterByDefaultCategory(true) ->findOne() ; - +var_dump($productCategory); +exit; if ($productCategory == null || $productCategory->getCategoryId() != $defaultCategoryId) { // Delete the old default category @@ -120,8 +121,13 @@ class Product extends BaseProduct * Create a new product, along with the default category ID * * @param int $defaultCategoryId the default category ID of this product + * @param float $basePrice the product base price + * @param int $priceCurrencyId the price currency Id + * @param int $taxRuleId the product tax rule ID + * @param float $baseWeight base weight in Kg */ - public function create($defaultCategoryId) { + + public function create($defaultCategoryId, $basePrice, $priceCurrencyId, $taxRuleId, $baseWeight) { $con = Propel::getWriteConnection(ProductTableMap::DATABASE_NAME); @@ -139,6 +145,8 @@ class Product extends BaseProduct // Set the position $this->setPosition($this->getNextPosition())->save($con); + $this->setTaxRuleId($taxRuleId); + // Create an empty product sale element $sale_elements = new ProductSaleElements(); @@ -147,7 +155,8 @@ class Product extends BaseProduct ->setRef($this->getRef()) ->setPromo(0) ->setNewness(0) - ->setWeight(0) + ->setWeight($baseWeight) + ->setIsDefault(true) ->save($con) ; @@ -156,9 +165,9 @@ class Product extends BaseProduct $product_price ->setProductSaleElements($sale_elements) - ->setPromoPrice(0) - ->setPrice(0) - ->setCurrency(CurrencyQuery::create()->findOneByByDefault(true)) + ->setPromoPrice($basePrice) + ->setPrice($basePrice) + ->setCurrencyId($priceCurrencyId) ->save($con) ; diff --git a/core/lib/Thelia/Model/ProductAssociatedContent.php b/core/lib/Thelia/Model/ProductAssociatedContent.php index e07ee2cd6..843d76ba1 100644 --- a/core/lib/Thelia/Model/ProductAssociatedContent.php +++ b/core/lib/Thelia/Model/ProductAssociatedContent.php @@ -11,11 +11,22 @@ class ProductAssociatedContent extends BaseProductAssociatedContent { use \Thelia\Model\Tools\ModelEventDispatcherTrait; + use \Thelia\Model\Tools\PositionManagementTrait; + + /** + * Calculate next position relative to our product + */ + protected function addCriteriaToPositionQuery($query) { + $query->filterByProductId($this->getProductId()); + } + /** * {@inheritDoc} */ public function preInsert(ConnectionInterface $con = null) { + $this->setPosition($this->getNextPosition()); + $this->dispatchEvent(TheliaEvents::BEFORE_CREATEPRODUCT_ASSOCIATED_CONTENT, new ProductAssociatedContentEvent($this)); return true; diff --git a/install/faker.php b/install/faker.php index 2c82f5d1b..fd74447db 100755 --- a/install/faker.php +++ b/install/faker.php @@ -404,6 +404,7 @@ try { $stock->setPromo($faker->randomNumber(0,1)); $stock->setNewness($faker->randomNumber(0,1)); $stock->setWeight($faker->randomFloat(2, 100,10000)); + $stock->setIsDefault($i == 0); $stock->save(); $productPrice = new \Thelia\Model\ProductPrice(); diff --git a/install/insert.sql b/install/insert.sql index aa7573d12..ec4e1b02b 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -1153,7 +1153,7 @@ INSERT INTO `tax` (`id`, `type`, `serialized_requirements`, `created_at`, `upda INSERT INTO `tax_i18n` (`id`, `locale`, `title`) VALUES (1, 'fr_FR', 'TVA française à 19.6%'), - (1, 'en_UK', 'french 19.6% tax'); + (1, 'en_US', 'French 19.6% VAT'); INSERT INTO `tax_rule` (`id`, `is_default`, `created_at`, `updated_at`) VALUES @@ -1162,7 +1162,7 @@ INSERT INTO `tax_rule` (`id`, `is_default`, `created_at`, `updated_at`) INSERT INTO `tax_rule_i18n` (`id`, `locale`, `title`) VALUES (1, 'fr_FR', 'TVA française à 19.6%'), - (1, 'en_UK', 'french 19.6% tax'); + (1, 'en_US', 'French 19.6% VAT'); INSERT INTO `tax_rule_country` (`tax_rule_id`, `country_id`, `tax_id`, `position`, `created_at`, `updated_at`) VALUES diff --git a/templates/admin/default/ajax/product-attributes-tab.html b/templates/admin/default/ajax/product-attributes-tab.html index 2cccbfadf..a3215f215 100644 --- a/templates/admin/default/ajax/product-attributes-tab.html +++ b/templates/admin/default/ajax/product-attributes-tab.html @@ -31,7 +31,7 @@ - +
@@ -43,9 +43,6 @@ {* Check if a product template is defined *} - {loop name="product_template" type="template" id={$TEMPLATE|default:0}}{/loop} - - {ifloop rel="product_template"}

{intl l='Product Attributes and Features'}

@@ -70,10 +67,18 @@

{intl l='Product Attributes'}

-

{intl - l="You can change attributes and their positions in the template configuration page." +

+ {if $TEMPLATE} + {intl + l="You can change template attributes and their positions in the template configuration page." tpl_mgmt_url={url path='/admin/configuration/templates/update' template_id=$TEMPLATE} - } + } + {else} + {intl + l="You can change attributes and their positions in the attributes configuration page." + tpl_mgmt_url={url path='/admin/configuration/attributes'} + } + {/if}

Please code me baby, oh yeah ! Code me NOW !
@@ -88,10 +93,18 @@

{intl l='Product Features'}

-

{intl - l="You can change feature products and their positions in the template configuration page." - tpl_mgmt_url={url path='/admin/configuration/templates/update' template_id=$TEMPLATE} - } +

+ {if $TEMPLATE} + {intl + l="You can change templates features and their positions in the template configuration page." + tpl_mgmt_url={url path='/admin/configuration/templates/update' template_id=$TEMPLATE} + } + {else} + {intl + l="You can change feature and their positions in the features configuration page." + tpl_mgmt_url={url path='/admin/configuration/features'} + } + {/if}

@@ -139,7 +152,7 @@
- {intl l='Use ctrl+clic to select more than one value. You can also clear selected values.' id=$ID} + {intl l='Use Ctrl+click to select more than one value. You can also clear selected values.' id=$ID} {/ifloop} @@ -179,18 +192,7 @@
- {/ifloop} - {elseloop rel="product_template"} -
-
-

{* <---- FIXME Lame ! *} -
- {intl l="This product is not attached to any product template. If you want to use features or attributes on this product, please select the proper template. You can define product templates in the Configuration section."} -
-
-
- {/elseloop}
{/loop} diff --git a/templates/admin/default/ajax/product-prices-tab.html b/templates/admin/default/ajax/product-prices-tab.html new file mode 100644 index 000000000..2878e1d9d --- /dev/null +++ b/templates/admin/default/ajax/product-prices-tab.html @@ -0,0 +1,75 @@ +{loop name="product_edit" type="product" visible="*" id=$product_id backend_context="1" lang=$edit_language_id} +
+ +
+
+
{intl l="Basic product information"}
+
+ +
+ +
+
+ {form_field form=$form field='price'} +
+ + {loop type="currency" name="default-currency" default_only="1" backend_context="1"} + +
+ + {$SYMBOL} +
+
{intl l='Enter here the product price in the default currency (%title)' title=$NAME}
+ + {form_field form=$form field='currency'} + + {/form_field} + + {/loop} +
+ {/form_field} +
+ +
+ {form_field form=$form field='tax_rule'} +
+ +
+ +
+ +
{intl l='Select here the tax applicable to this product'}
+ +
+ {/form_field} +
+ +
+ Price w/tax +
+
+ + {form_field form=$form field='weight'} +
+ + +
+
+
+ + {intl l="Kg"} +
+
+
+ +
{intl l='Enter here the product weight, in Kilogrammes'}
+
+ {/form_field} +
+
+{/loop} \ No newline at end of file diff --git a/templates/admin/default/ajax/product-related-tab.html b/templates/admin/default/ajax/product-related-tab.html index 8d705e9ae..977ecf83c 100644 --- a/templates/admin/default/ajax/product-related-tab.html +++ b/templates/admin/default/ajax/product-related-tab.html @@ -9,228 +9,347 @@ close_url = "{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}" } - {* -- Begin related content management -- *} +
-
-
- + +
+ + {* -- Begin categories management ----------------------------------- *} + +
+
+
+ {elseloop rel="categories"} +
{intl l="No categories found"}
+ {/elseloop} -
-
- {intl l="No available content in this folder"} -
-
- {/ifloop} + +
- {elseloop rel="folders"} -
{intl l="No folders found"}
- {/elseloop} +
+ + + + - - + -
-
{intl l='ID'}{intl l='Category title'}
- - - + {module_include location='product_categories_table_header'} - + + + - {module_include location='product_contents_table_header'} + + {loop name="additional_categories" type="category" product=$product_id exclude=$DEFAULT_CATEGORY backend_context="1" lang="$edit_language_id"} + + - - - + - - {loop name="assigned_contents" type="associated_content" product="$product_id" backend_context="1" lang="$edit_language_id"} - - + {module_include location='product_categories_table_row'} - - - {module_include location='product_contents_table_row'} - - - - {/loop} - - {elseloop rel="assigned_contents"} - - - - {/elseloop} - -
{intl l='ID'}{intl l='Content title'}{intl l="Actions"}
{$ID}{intl l="Actions"}
+ {$TITLE} +
{$ID} - {$TITLE} - -
- {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.product.content.delete"} - - - - {/loop} -
-
-
- {intl l="This product contains no contents"} -
-
-
-
- - {* -- End related content management ---- *} - - {* -- Begin accessories management ------ *} - -
-
-
- -

{intl l='Product accessories'}

-

{intl l='Define here this product\'s accessories'}

- - - - - {ifloop rel="categories"} -
-
+
+ {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.product.category.delete"} + + + + {/loop} +
+
- - - - - - - - - {module_include location='product_accessories_table_header'} - - - - - - - {loop name="assigned_accessories" order="accessory" type="accessory" product="$product_id" backend_context="1" lang="$edit_language_id"} - - - - - - - - {module_include location='product_accessories_table_row'} - - - - {/loop} - - {elseloop rel="assigned_accessories"} - - - - {/elseloop} - -
{intl l='ID'}{intl l='Accessory title'}{intl l='Position'}{intl l="Actions"}
{$ID} - {$TITLE} - - {admin_position_block - permission="admin.products.edit" - path={url path='/admin/product/update-accessory-position' product_id=$product_id current_tab="related"} - url_parameter="accessory_id" - in_place_edit_class="accessoryPositionChange" - position=$POSITION - id=$ID - } - -
- {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.product.accessory.delete"} - - - - {/loop} -
-
-
- {intl l="This product contains no accessories"} -
-
+ {elseloop rel="additional_categories"} + + +
+ {intl l="This product doesn't belong to any additional category."} +
+ + + {/elseloop} + + +
+ {* -- End categories management ------------------------------------- *}
- {* -- End accessories management -------- *} -
{* Delete related content confirmation dialog *} @@ -275,6 +394,26 @@ form_content = {$smarty.capture.delete_accessory_dialog nofilter} } +{* Delete category confirmation dialog *} + +{capture "delete_category_dialog"} + + + + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "delete_category_dialog" + dialog_title = {intl l="Remove from category"} + dialog_message = {intl l="Do you really want to remove the product from this category ?"} + + form_action = {url path='/admin/products/category/delete'} + form_content = {$smarty.capture.delete_category_dialog nofilter} +} + + + {/block} \ No newline at end of file diff --git a/templates/admin/default/template-edit.html b/templates/admin/default/template-edit.html index 8cc6a0e7e..17e48b950 100644 --- a/templates/admin/default/template-edit.html +++ b/templates/admin/default/template-edit.html @@ -59,30 +59,32 @@ {/form}
+ -
-
-
+
+
+
+

{intl l='Attributes'}

Manage attributes included in this product templates

+
+
-
- -
+
+

{intl l='Features'}

Manage features included in this product templates

-
+
-
- +
From 5846a5f2881bbef44e0a46ce85a89012376aca4f Mon Sep 17 00:00:00 2001 From: gmorel Date: Mon, 23 Sep 2013 11:55:02 +0200 Subject: [PATCH 16/43] Working : Upload management : on folder, category, product --- templates/admin/default/folder-edit.html | 92 +++--- .../default/includes/image-upload-form.html | 11 - templates/admin/default/product-edit.html | 287 +++++++++--------- 3 files changed, 196 insertions(+), 194 deletions(-) diff --git a/templates/admin/default/folder-edit.html b/templates/admin/default/folder-edit.html index 26795b7aa..ebbc8582a 100644 --- a/templates/admin/default/folder-edit.html +++ b/templates/admin/default/folder-edit.html @@ -246,6 +246,7 @@
+ {include file='includes/image-upload-form.html' imageType='folder' parentId=$folder_id}
@@ -286,59 +287,64 @@ {/block} {block name="javascript-initialization"} - + {/javascripts} + {javascripts file='assets/js/image-upload.js'} + + {/javascripts} + + {/block} \ No newline at end of file diff --git a/templates/admin/default/includes/image-upload-form.html b/templates/admin/default/includes/image-upload-form.html index 46c949841..89da09f13 100644 --- a/templates/admin/default/includes/image-upload-form.html +++ b/templates/admin/default/includes/image-upload-form.html @@ -20,17 +20,6 @@ Parameters:
-{*{block name="javascript-initialization"}*} - {*{$smarty.block.parent}*} - - {*{javascripts file='assets/js/image-upload.js'}*} - {**} - {*{/javascripts}*} - {*{javascripts file='assets/js/dropzone.js'}*} - {**} - {*{/javascripts}*} -{*{/block}*} - + {/javascripts} + {javascripts file='assets/js/image-upload.js'} + + {/javascripts} -{javascripts file='assets/js/bootstrap-editable/bootstrap-editable.js'} - -{/javascripts} + {javascripts file='assets/js/bootstrap-editable/bootstrap-editable.js'} + + {/javascripts} - - + + - + $.each(json, function(idx, value) { + $('#content_id').append($('
+ + Thelia\Controller\Admin\FileController::getImageFormAjaxAction + .* + \d+ + Thelia\Controller\Admin\FileController::getImageListAjaxAction .* diff --git a/core/lib/Thelia/Controller/Admin/FileController.php b/core/lib/Thelia/Controller/Admin/FileController.php index 2592db192..1b2e3b21b 100755 --- a/core/lib/Thelia/Controller/Admin/FileController.php +++ b/core/lib/Thelia/Controller/Admin/FileController.php @@ -138,6 +138,23 @@ class FileController extends BaseAdminController return $this->render('includes/image-upload-list-ajax', $args); } + /** + * Manage how an image list will be uploaded in AJAX + * + * @param int $parentId Parent id owning images being saved + * @param string $parentType Parent Type owning images being saved + * + * @return Response + */ + public function getImageFormAjaxAction($parentId, $parentType) + { + $this->checkAuth('ADMIN', 'admin.image.save'); + $this->checkXmlHttpRequest(); + $args = array('imageType' => $parentType, 'parentId' => $parentId); + + return $this->render('includes/image-upload-form', $args); + } + /** * Manage how an image is viewed * diff --git a/core/lib/Thelia/Tools/FileManager.php b/core/lib/Thelia/Tools/FileManager.php index 4b1d90e89..6b37bfb30 100644 --- a/core/lib/Thelia/Tools/FileManager.php +++ b/core/lib/Thelia/Tools/FileManager.php @@ -413,7 +413,7 @@ class FileManager $uri = '/admin/content/update/' . $parentId; break; case ImagesCreateOrUpdateEvent::TYPE_FOLDER: - $uri = '/admin/folders/update?folder_id=' . $parentId; + $uri = '/admin/folders/update/' . $parentId; break; default: $uri = false; diff --git a/templates/admin/default/product-edit.html b/templates/admin/default/product-edit.html index d9cda2f8d..e7dfd50ef 100644 --- a/templates/admin/default/product-edit.html +++ b/templates/admin/default/product-edit.html @@ -62,7 +62,13 @@ data-toggle="tab">{intl l="Associations"} -
  • {intl l="Images"}
  • +
  • + + {intl l="Images"} + +
  • {intl l="Documents"}
  • {intl l="Modules"}
  • From d0376d31f933159bea8a4d3c9d7839ef696084e1 Mon Sep 17 00:00:00 2001 From: gmorel Date: Mon, 23 Sep 2013 14:42:23 +0200 Subject: [PATCH 21/43] Working : Upload image : set product image form loaded via ajax, fix category, folder, content --- .../admin/default/assets/js/image-upload.js | 33 +-- templates/admin/default/category-edit.html | 1 + templates/admin/default/content-edit.html | 2 +- templates/admin/default/folder-edit.html | 1 + templates/admin/default/product-edit.html | 233 +++++++++--------- 5 files changed, 141 insertions(+), 129 deletions(-) diff --git a/templates/admin/default/assets/js/image-upload.js b/templates/admin/default/assets/js/image-upload.js index bbeed9ea3..92d2a651b 100644 --- a/templates/admin/default/assets/js/image-upload.js +++ b/templates/admin/default/assets/js/image-upload.js @@ -1,23 +1,26 @@ $(function($){ // Manage picture upload - var pictureUploadManager = {}; + $.imageUploadManager = {}; Dropzone.autoDiscover = false; + // Remove image on click + $.imageUploadManager.initImageDropZone = function() { + var imageDropzone = new Dropzone("#images-dropzone", { + dictDefaultMessage : $('.btn-browse').html(), + uploadMultiple: false, + maxFilesize: 8 + }); - var imageDropzone = new Dropzone("#images-dropzone", { - dictDefaultMessage : $('.btn-browse').html(), - uploadMultiple: false, - maxFilesize: 8 - }); - - imageDropzone.on("success", function(file) { - $(".image-manager .dz-file-preview").remove(); - imageDropzone.removeFile(file); - pictureUploadManager.updateImageListAjax(); - }); + imageDropzone.on("success", function(file) { + $(".image-manager .dz-file-preview").remove(); + imageDropzone.removeFile(file); + $.imageUploadManager.updateImageListAjax(); + $.imageUploadManager.onClickDeleteImage(); + }); + }; // Update picture list via AJAX call - pictureUploadManager.updateImageListAjax = function() { + $.imageUploadManager.updateImageListAjax = function() { var $imageListArea = $(".image-manager .existing-image"); $imageListArea.html('
    '); $.ajax({ @@ -38,7 +41,7 @@ $(function($){ }; // Remove image on click - pictureUploadManager.onClickDeleteImage = function() { + $.imageUploadManager.onClickDeleteImage = function() { $('.image-manager .image-delete-btn').on('click', function (e) { e.preventDefault(); var $this = $(this); @@ -67,5 +70,5 @@ $(function($){ return false; }); }; - pictureUploadManager.onClickDeleteImage(); + $.imageUploadManager.onClickDeleteImage(); }); diff --git a/templates/admin/default/category-edit.html b/templates/admin/default/category-edit.html index db1e3f14f..b7e1d9ed9 100755 --- a/templates/admin/default/category-edit.html +++ b/templates/admin/default/category-edit.html @@ -326,6 +326,7 @@ }); $(function() { + $.imageUploadManager.initImageDropZone(); $('.use_default_rewriten_url').click(function(ev) { alert("Not functionnal"); diff --git a/templates/admin/default/content-edit.html b/templates/admin/default/content-edit.html index bb30328c4..f4eb063cf 100644 --- a/templates/admin/default/content-edit.html +++ b/templates/admin/default/content-edit.html @@ -295,8 +295,8 @@ form_content = {$smarty.capture.delete_content_dialog nofilter} {/javascripts} -{/javascripts} + {javascripts file='assets/js/dropzone.js'} + + {/javascripts} + {javascripts file='assets/js/image-upload.js'} + + {/javascripts} + {javascripts file='assets/js/bootstrap-editable/bootstrap-editable.js'} + + {/javascripts} - - + + - + $.each(json, function(idx, value) { + $('#attribute_value_id').append($('