Merge branch 'catalog' of https://github.com/thelia/thelia into upload_management

# By franck
# Via franck
* 'catalog' of https://github.com/thelia/thelia:
  Finished combination creation GUI
  Put curresncy selector in toolbar
  Started price tab
  Finished product multiple categories attachment
  Ajaxified product modification tabs
  Finished product features management
  Aded feature_template and category_template position management
  Finished product feature values
  Fixed product update process
  Added missing files
  Working catalog branch

Conflicts:
	core/lib/Thelia/Action/BaseAction.php
	install/insert.sql
	local/config/schema.xml
	templates/admin/default/folders.html
	templates/admin/default/product-edit.html
This commit is contained in:
gmorel
2013-09-23 12:27:36 +02:00
81 changed files with 5045 additions and 2297 deletions

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -24,6 +24,9 @@ namespace Thelia\Action;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Thelia\Model\AdminLog;
use Propel\Runtime\ActiveQuery\PropelQuery;
use Propel\Runtime\ActiveQuery\ModelCriteria;
use Thelia\Core\Event\UpdatePositionEvent;
class BaseAction
{
@@ -47,6 +50,30 @@ 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();
}
}
/**
* Helper to append a message to the admin log.
*

View File

@@ -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) {

View File

@@ -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);
}
/**

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -48,6 +48,19 @@ 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;
use Thelia\Model\ProductCategoryQuery;
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
{
@@ -71,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);
@@ -84,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
@@ -96,11 +115,16 @@ class Product extends BaseAction implements EventSubscriberInterface
->setDescription($event->getDescription())
->setChapo($event->getChapo())
->setPostscriptum($event->getPostscriptum())
->setParent($event->getParent())
->setVisible($event->getVisible())
->save();
->save()
;
// Update the rewriten URL, if required
$product->setRewrittenUrl($event->getLocale(), $event->getUrl());
// Update default category (ifd required)
$product->updateDefaultCategory($event->getDefaultCategory());
$event->setProduct($product);
}
@@ -147,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) {
@@ -193,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()
@@ -224,27 +264,96 @@ class Product extends BaseAction implements EventSubscriberInterface
;
}
public function setProductTemplate(ProductSetTemplateEvent $event) {
$product = $event->getProduct();
// Delete all product feature relations
FeatureProductQuery::create()->filterByProduct($product)->delete();
// Delete all product attributes sale elements
ProductSaleElementsQuery::create()->filterByProduct($product)->delete();
// Update the product template
$template_id = $event->getTemplateId();
// Set it to null if it's zero.
if ($template_id <= 0) $template_id = NULL;
$product->setTemplateId($template_id)->save();
}
/**
* Changes accessry position, selecting absolute ou relative change.
*
* @param ProductChangePositionEvent $event
*/
public function updateAccessoryPosition(UpdatePositionEvent $event)
{
return $this->genericUpdatePosition(AccessoryQuery::create(), $event);
}
/**
* Changes position, selecting absolute ou relative change.
*
* @param ProductChangePositionEvent $event
*/
public function updateAccessoryPosition(UpdatePositionEvent $event)
public function updateContentPosition(UpdatePositionEvent $event)
{
if (null !== $accessory = AccessoryQuery::create()->findPk($event->getObjectId())) {
return $this->genericUpdatePosition(ProductAssociatedContentQuery::create(), $event);
}
$accessory->setDispatcher($this->getDispatcher());
public function updateFeatureProductValue(FeatureProductUpdateEvent $event) {
$mode = $event->getMode();
// 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.
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();
$featureProductQuery = FeatureProductQuery::create()
->filterByFeatureId($event->getFeatureId())
->filterByProductId($event->getProductId())
;
if ($event->getIsTextValue() !== true) {
$featureProductQuery->filterByFeatureAvId($event->getFeatureValue());
}
$featureProduct = $featureProductQuery->findOne();
if ($featureProduct == null) {
$featureProduct = new FeatureProduct();
$featureProduct
->setDispatcher($this->getDispatcher())
->setProductId($event->getProductId())
->setFeatureId($event->getFeatureId())
;
}
if ($event->getIsTextValue() == true) {
$featureProduct->setFreeTextValue($event->getFeatureValue());
}
else {
$featureProduct->setFeatureAvId($event->getFeatureValue());
}
$featureProduct->save();
$event->setFeatureProduct($featureProduct);
}
public function deleteFeatureProductValue(FeatureProductDeleteEvent $event) {
$featureProduct = FeatureProductQuery::create()
->filterByProductId($event->getProductId())
->filterByFeatureId($event->getFeatureId())
->delete()
;
}
/**
@@ -263,9 +372,19 @@ class Product extends BaseAction implements EventSubscriberInterface
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),
TheliaEvents::PRODUCT_FEATURE_DELETE_VALUE => array("deleteFeatureProductValue", 128),
);
}
}

View File

@@ -135,6 +135,26 @@ class Template extends BaseAction implements EventSubscriberInterface
}
}
/**
* Changes position, selecting absolute ou relative change.
*
* @param CategoryChangePositionEvent $event
*/
public function updateAttributePosition(UpdatePositionEvent $event)
{
return $this->genericUpdatePosition(AttributeTemplateQuery::create(), $event);
}
/**
* Changes position, selecting absolute ou relative change.
*
* @param CategoryChangePositionEvent $event
*/
public function updateFeaturePosition(UpdatePositionEvent $event)
{
return $this->genericUpdatePosition(FeatureTemplateQuery::create(), $event);
}
public function deleteAttribute(TemplateDeleteAttributeEvent $event) {
$attribute_template = AttributeTemplateQuery::create()
@@ -185,6 +205,9 @@ class Template extends BaseAction implements EventSubscriberInterface
TheliaEvents::TEMPLATE_ADD_FEATURE => array("addFeature", 128),
TheliaEvents::TEMPLATE_DELETE_FEATURE => array("deleteFeature", 128),
TheliaEvents::TEMPLATE_CHANGE_ATTRIBUTE_POSITION => array('updateAttributePosition', 128),
TheliaEvents::TEMPLATE_CHANGE_FEATURE_POSITION => array('updateFeaturePosition', 128),
);
}
}

View File

@@ -62,6 +62,7 @@
<form name="thelia.admin.product.creation" class="Thelia\Form\ProductCreationForm"/>
<form name="thelia.admin.product.modification" class="Thelia\Form\ProductModificationForm"/>
<form name="thelia.admin.product.details.modification" class="Thelia\Form\ProductDetailsModificationForm"/>
<form name="thelia.admin.product.creation" class="Thelia\Form\ProductCreationForm"/>
<form name="thelia.admin.product.deletion" class="Thelia\Form\ProductModificationForm"/>

View File

@@ -180,22 +180,47 @@
<default key="_controller">Thelia\Controller\Admin\ProductController::updatePositionAction</default>
</route>
<!-- Related content -->
<route id="admin.products.related-content.add" path="/admin/products/related-content/add">
<route id="admin.products.general.tab" path="/admin/products/general/tab">
<default key="_controller">Thelia\Controller\Admin\ProductController::loadGeneralAjaxTabAction</default>
</route>
<!-- Product associations, categories, content and accessories -->
<route id="admin.products.related.tab" path="/admin/products/related/tab">
<default key="_controller">Thelia\Controller\Admin\ProductController::loadRelatedAjaxTabAction</default>
</route>
<!-- categories -->
<route id="admin.products.additional-category.add" path="/admin/products/category/add">
<default key="_controller">Thelia\Controller\Admin\ProductController::addAdditionalCategoryAction</default>
</route>
<route id="admin.products.additional-category.delete" path="/admin/products/category/delete">
<default key="_controller">Thelia\Controller\Admin\ProductController::deleteAdditionalCategoryAction</default>
</route>
<!-- content -->
<route id="admin.products.related-content.add" path="/admin/products/content/add">
<default key="_controller">Thelia\Controller\Admin\ProductController::addRelatedContentAction</default>
</route>
<route id="admin.products.related-content.delete" path="/admin/products/related-content/delete">
<route id="admin.products.related-content.delete" path="/admin/products/content/delete">
<default key="_controller">Thelia\Controller\Admin\ProductController::deleteRelatedContentAction</default>
</route>
<route id="admin.product.available-related-content" path="/admin/product/{productId}/available-related-content/{folderId}.{_format}" methods="GET">
<route id="admin.product.available-related-content" path="/admin/product/{productId}/available-content/{folderId}.{_format}" methods="GET">
<default key="_controller">Thelia\Controller\Admin\ProductController::getAvailableRelatedContentAction</default>
<requirement key="_format">xml|json</requirement>
</route>
<!-- Product accessories -->
<route id="admin.product.update-content-position" path="/admin/product/update-content-position">
<default key="_controller">Thelia\Controller\Admin\ProductController::updateContentPositionAction</default>
</route>
<!-- accessories -->
<route id="admin.products.accessories.add" path="/admin/products/accessory/add">
<default key="_controller">Thelia\Controller\Admin\ProductController::addAccessoryAction</default>
@@ -210,18 +235,40 @@
<requirement key="_format">xml|json</requirement>
</route>
<route id="admin.products.update-accessory-position" path="/admin/products/update-accessory-position">
<route id="admin.product.update-accessory-position" path="/admin/product/update-accessory-position">
<default key="_controller">Thelia\Controller\Admin\ProductController::updateAccessoryPositionAction</default>
</route>
<!--Features and attributes -->
<!--Product Features and attributes -->
<route id="admin.products.attributes.tab" path="/admin/products/attributes/tab">
<default key="_controller">Thelia\Controller\Admin\ProductController::loadAttributesAjaxTabAction</default>
</route>
<route id="admin.products.set-product-template" path="/admin/product/{productId}/set-product-template">
<default key="_controller">Thelia\Controller\Admin\ProductController::setProductTemplateAction</default>
</route>
<route id="admin.products.update-attributes-and-features" path="/admin/product/{productId}/update-attributes-and-features">
<default key="_controller">Thelia\Controller\Admin\ProductController::updateAttributesAndFeaturesAction</default>
</route>
<!-- Combinations -->
<route id="admin.product.attribute-values" path="/admin/product/{productId}/attribute-values/{attributeId}.{_format}" methods="GET">
<default key="_controller">Thelia\Controller\Admin\ProductController::getAttributeValuesAction</default>
<requirement key="_format">xml|json</requirement>
</route>
<route id="admin.product.add-attribute-value-to-combination" path="/admin/product/{productId}/add-attribute-value-to-combination/{attributeAvId}/{combination}.{_format}" methods="GET">
<default key="_controller">Thelia\Controller\Admin\ProductController::addAttributeValueToCombinationAction</default>
<requirement key="_format">xml|json</requirement>
</route>
<!-- Folder routes management -->
<route id="admin.folders.default" path="/admin/folders">
<default key="_controller">Thelia\Controller\Admin\FolderController::defaultAction</default>
</route>
@@ -411,6 +458,10 @@
<default key="_controller">Thelia\Controller\Admin\TemplateController::deleteFeatureAction</default>
</route>
<route id="admin.configuration.templates.attributes.update-feature-position" path="/admin/template/update-feature-position">
<default key="_controller">Thelia\Controller\Admin\TemplateController::updateFeaturePositionAction</default>
</route>
<route id="admin.configuration.templates.attributes.list" path="/admin/configuration/templates/attributes/list">
<default key="_controller">Thelia\Controller\Admin\TemplateController::getAjaxAttributesAction</default>
</route>
@@ -423,6 +474,10 @@
<default key="_controller">Thelia\Controller\Admin\TemplateController::deleteAttributeAction</default>
</route>
<route id="admin.configuration.templates.attributes.update-attribute-position" path="/admin/template/update-attribute-position">
<default key="_controller">Thelia\Controller\Admin\TemplateController::updateAttributePositionAction</default>
</route>
<!-- attribute and attributes value management -->

View File

@@ -58,6 +58,7 @@ abstract class AbstractCrudController extends BaseAdminController
* @param string $objectName the lower case object name. Example. "message"
*
* @param string $defaultListOrder the default object list order, or null if list is not sortable. Example: manual
* @param string $orderRequestParameterName Name of the request parameter that set the list order (null if list is not sortable)
*
* @param string $viewPermissionIdentifier the 'view' permission identifier. Example: "admin.configuration.message.view"
* @param string $createPermissionIdentifier the 'create' permission identifier. Example: "admin.configuration.message.create"
@@ -445,6 +446,8 @@ abstract class AbstractCrudController extends BaseAdminController
/**
* Update object position (only for objects whichsupport that)
*
* FIXME: integrate with genericUpdatePositionAction
*/
public function updatePositionAction()
{
@@ -482,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)
*/

View File

@@ -250,6 +250,23 @@ class BaseAdminController extends BaseController
$this->redirect(URL::getInstance()->absoluteUrl($this->getRoute($routeId), $urlParameters));
}
/**
* Get the current edition currency ID, checking if a change was requested in the current request.
*/
protected function getCurrentEditionCurrency()
{
// Return the new language if a change is required.
if (null !== $edit_currency_id = $this->getRequest()->get('edit_currency_id', null)) {
if (null !== $edit_currency = LangQuery::create()->findOneById($edit_currency_id)) {
return $edit_currency;
}
}
// Otherwise return the lang stored in session.
return $this->getSession()->getAdminEditionCurrency();
}
/**
* Get the current edition lang ID, checking if a change was requested in the current request.
*/
@@ -376,6 +393,9 @@ class BaseAdminController extends BaseController
// Find the current edit language ID
$edition_language = $this->getCurrentEditionLang();
// Find the current edit currency ID
$edition_currency = $this->getCurrentEditionCurrency();
// Prepare common template variables
$args = array_merge($args, array(
'locale' => $session->getLang()->getLocale(),
@@ -385,11 +405,16 @@ class BaseAdminController extends BaseController
'edit_language_id' => $edition_language->getId(),
'edit_language_locale' => $edition_language->getLocale(),
'edit_currency_id' => $edition_currency->getId(),
'current_url' => $this->getRequest()->getUri()
));
// Update the current edition language in session
$this->getSession()->setAdminEditionLang($edition_language);
// Update the current edition language & currency in session
$this->getSession()
->setAdminEditionLang($edition_language)
->setAdminEditionCurrency($edition_currency)
;
// Render the template.
try {

View File

@@ -43,6 +43,16 @@ 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;
use Thelia\Core\Event\ProductSetTemplateEvent;
use Thelia\Model\Base\ProductSaleElementsQuery;
use Thelia\Core\Event\ProductAddCategoryEvent;
use Thelia\Core\Event\ProductDeleteCategoryEvent;
use Thelia\Model\AttributeQuery;
use Thelia\Model\AttributeAvQuery;
/**
* Manages products
@@ -72,6 +82,35 @@ class ProductController extends AbstractCrudController
);
}
/**
* Attributes ajax tab loading
*/
public function loadAttributesAjaxTabAction() {
return $this->render(
'ajax/product-attributes-tab',
array(
'product_id' => $this->getRequest()->get('product_id', 0),
)
);
}
/**
* Related information ajax tab loading
*/
public function loadRelatedAjaxTabAction() {
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)
)
);
}
protected function getCreationForm()
{
return new ProductCreationForm($this->getRequest());
@@ -92,6 +131,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;
@@ -110,8 +153,8 @@ class ProductController extends AbstractCrudController
->setPostscriptum($formData['postscriptum'])
->setVisible($formData['visible'])
->setUrl($formData['url'])
->setParent($formData['parent'])
;
->setDefaultCategory($formData['default_category'])
;
return $changeEvent;
}
@@ -137,9 +180,15 @@ 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(),
'ref' => $object->getRef(),
'locale' => $object->getLocale(),
'title' => $object->getTitle(),
'chapo' => $object->getChapo(),
@@ -148,6 +197,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
@@ -179,10 +230,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')
);
}
@@ -417,7 +468,6 @@ class ProductController extends AbstractCrudController
public function deleteAccessoryAction()
{
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.products.update")) return $response;
@@ -443,35 +493,249 @@ class ProductController extends AbstractCrudController
}
/**
* Update accessory position (only for objects whichsupport that)
* Update accessory position
*/
public function updateAccessoryPositionAction()
{
$accessory = AccessoryQuery::create()->findPk($this->getRequest()->get('accessory_id', null));
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.
*
* @param unknown $productId
*/
public function setProductTemplateAction($productId) {
// Check current user authorization
if (null !== $response = $this->checkAuth('admin.products.update')) return $response;
try {
$mode = $this->getRequest()->get('mode', null);
$product = ProductQuery::create()->findPk($productId);
if ($mode == 'up')
$mode = UpdatePositionEvent::POSITION_UP;
else if ($mode == 'down')
$mode = UpdatePositionEvent::POSITION_DOWN;
else
$mode = UpdatePositionEvent::POSITION_ABSOLUTE;
if ($product != null) {
$position = $this->getRequest()->get('position', null);
$template_id = intval($this->getRequest()->get('template_id', 0));
$event = new UpdatePositionEvent($mode, $position);
$this->dispatch(TheliaEvents::PRODUCT_UPDATE_ACCESSORY_POSITION, $event);
}
catch (\Exception $ex) {
// Any error
return $this->errorPage($ex);
$this->dispatch(
TheliaEvents::PRODUCT_SET_TEMPLATE,
new ProductSetTemplateEvent($product, $template_id)
);
}
$this->redirectToEditionTemplate();
}
/**
* Update product attributes and features
*/
public function updateAttributesAndFeaturesAction($productId) {
$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, starting with feature av. values
$featureValues = $this->getRequest()->get('feature_value', array());
foreach($featureValues as $featureId => $featureValueList) {
// Delete all features av. for this feature.
$event = new FeatureProductDeleteEvent($productId, $featureId);
$this->dispatch(TheliaEvents::PRODUCT_FEATURE_DELETE_VALUE, $event);
// Add then 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());
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());
$this->dispatch(TheliaEvents::PRODUCT_FEATURE_DELETE_VALUE, $event);
}
}
}
}
// If we have to stay on the same page, do not redirect to the succesUrl,
// just redirect to the edit page again.
if ($this->getRequest()->get('save_mode') == 'stay') {
$this->redirectToEditionTemplate($this->getRequest());
}
// Redirect to the 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();
}
// -- Product combination management ---------------------------------------
public function getAttributeValuesAction($productId, $attributeId) {
$result = array();
// Get attribute for this product
$attribute = AttributeQuery::create()->findPk($attributeId);
if ($attribute !== null) {
$values = AttributeAvQuery::create()
->joinWithI18n($this->getCurrentEditionLocale())
->filterByAttribute($attribute)
->find();
;
if ($values !== null) {
foreach($values as $value) {
$result[] = array('id' => $value->getId(), 'title' => $value->getTitle());
}
}
}
return $this->jsonResponse(json_encode($result));
}
public function addAttributeValueToCombinationAction($productId, $attributeAvId, $combination) {
$result = array();
// Get attribute for this product
$attributeAv = AttributeAvQuery::create()->joinWithI18n($this->getCurrentEditionLocale())->findPk($attributeAvId);
if ($attributeAv !== null) {
$addIt = true;
// Check if this attribute is not already present
$combinationArray = explode(',', $combination);
foreach ($combinationArray as $id) {
$attrAv = AttributeAvQuery::create()->joinWithI18n($this->getCurrentEditionLocale())->findPk($id);
if ($attrAv !== null) {
if ($attrAv->getAttributeId() == $attributeAv->getAttributeId()) {
$attribute = AttributeQuery::create()->joinWithI18n($this->getCurrentEditionLocale())->findPk($attributeAv->getAttributeId());
$result['error'] = $this->getTranslator()->trans(
'A value for attribute "%name" is already present in the combination',
array('%name' => $attribute->getTitle())
);
$addIt = false;
}
$result[] = array('id' => $attrAv->getId(), 'title' => $attrAv->getTitle());
}
}
if ($addIt) $result[] = array('id' => $attributeAv->getId(), 'title' => $attributeAv->getTitle());
}
return $this->jsonResponse(json_encode($result));
}
}

View File

@@ -39,6 +39,8 @@ use Thelia\Core\Event\TemplateDeleteAttributeEvent;
use Thelia\Core\Event\TemplateAddAttributeEvent;
use Thelia\Core\Event\TemplateAddFeatureEvent;
use Thelia\Core\Event\TemplateDeleteFeatureEvent;
use Thelia\Model\FeatureTemplateQuery;
use Thelia\Model\AttributeTemplateQuery;
/**
* Manages product templates
@@ -255,6 +257,21 @@ class TemplateController extends AbstractCrudController
$this->redirectToEditionTemplate();
}
public function updateAttributePositionAction() {
// Find attribute_template
$attributeTemplate = AttributeTemplateQuery::create()
->filterByTemplateId($this->getRequest()->get('template_id', null))
->filterByAttributeId($this->getRequest()->get('attribute_id', null))
->findOne()
;
return $this->genericUpdatePositionAction(
$attributeTemplate,
TheliaEvents::TEMPLATE_CHANGE_ATTRIBUTE_POSITION
);
}
public function addFeatureAction() {
// Check current user authorization
@@ -299,4 +316,18 @@ class TemplateController extends AbstractCrudController
$this->redirectToEditionTemplate();
}
public function updateFeaturePositionAction() {
// Find feature_template
$featureTemplate = FeatureTemplateQuery::create()
->filterByTemplateId($this->getRequest()->get('template_id', null))
->filterByFeatureId($this->getRequest()->get('feature_id', null))
->findOne()
;
return $this->genericUpdatePositionAction(
$featureTemplate,
TheliaEvents::TEMPLATE_CHANGE_FEATURE_POSITION
);
}
}

View File

@@ -0,0 +1,61 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Event;
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;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Event;
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;
}
}

View File

@@ -0,0 +1,89 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Event;
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;
}
}

View File

@@ -0,0 +1,48 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Event;
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;
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,50 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Event;
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;
}
}

View File

@@ -0,0 +1,51 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Event;
use Thelia\Model\Product;
use Thelia\Core\Event\ActionEvent;
class ProductSetTemplateEvent extends ProductEvent
{
public $template_id = null;
public function __construct(Product $product = null, $template_id)
{
parent::__construct($product);
$this->template_id = $template_id;
}
public function getTemplateId()
{
return $this->template_id;
}
public function setTemplateId($template_id)
{
$this->template_id = $template_id;
return $this;
}
}

View File

@@ -210,8 +210,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";
@@ -224,12 +224,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_ADD_ACCESSORY = "action.productAddAccessory";
const PRODUCT_REMOVE_ACCESSORY = "action.productRemoveAccessory";
const PRODUCT_UPDATE_ACCESSORY_POSITION = "action.updateProductPosition";
const PRODUCT_SET_TEMPLATE = "action.productSetTemplate";
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.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";
@@ -251,17 +260,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
*/
@@ -444,6 +464,7 @@ final class TheliaEvents
const AFTER_DELETECURRENCY = "action.after_deleteCurrency";
const CHANGE_DEFAULT_CURRENCY = 'action.changeDefaultCurrency';
// -- Product templates management -----------------------------------------
const TEMPLATE_CREATE = "action.createTemplate";
@@ -456,6 +477,9 @@ final class TheliaEvents
const TEMPLATE_ADD_FEATURE = "action.templateAddFeature";
const TEMPLATE_DELETE_FEATURE = "action.templateDeleteFeature";
const TEMPLATE_CHANGE_FEATURE_POSITION = "action.templateChangeAttributePosition";
const TEMPLATE_CHANGE_ATTRIBUTE_POSITION = "action.templateChangeFeaturePosition";
const BEFORE_CREATETEMPLATE = "action.before_createTemplate";
const AFTER_CREATETEMPLATE = "action.after_createTemplate";

View File

@@ -65,23 +65,6 @@ class Session extends BaseSession
return $this;
}
public function getAdminEditionLang()
{
$lang = $this->get('thelia.admin.edition.lang');
if (null === $lang) {
$lang = Lang::getDefaultLanguage();
}
return $lang;
}
public function setAdminEditionLang($langId)
{
$this->set('thelia.admin.edition.lang', $langId);
return $this;
}
public function setCurrency(Currency $currency)
{
$this->set("thelia.current.currency", $currency);
@@ -98,6 +81,43 @@ class Session extends BaseSession
return $currency;
}
// -- Admin lang and currency ----------------------------------------------
public function getAdminEditionCurrency()
{
$currency = $this->get('thelia.admin.edition.currency', null);
if (null === $currency) {
$currency = Currency::getDefaultCurrency();
}
return $currency;
}
public function setAdminEditionCurrency($currencyId)
{
$this->set('thelia.admin.edition.currency', $currencyId);
return $this;
}
public function getAdminEditionLang()
{
$lang = $this->get('thelia.admin.edition.lang');
if (null === $lang) {
$lang = Lang::getDefaultLanguage();
}
return $lang;
}
public function setAdminEditionLang($lang)
{
$this->set('thelia.admin.edition.lang', $lang);
return $this;
}
// -- Customer user --------------------------------------------------------
public function setCustomerUser(UserInterface $user)

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -41,7 +41,8 @@ use Thelia\Type\BooleanOrBothType;
use Thelia\Model\ProductQuery;
use Thelia\Model\TemplateQuery;
use Thelia\Model\AttributeTemplateQuery;
use Thelia\Core\Translation\Translator;
use Thelia\Model\Map\AttributeTemplateTableMap;
/**
*
* Attribute loop
@@ -106,33 +107,50 @@ class Attribute extends BaseI18nLoop
$product = $this->getProduct();
$template = $this->getTemplate();
if (null !== $product) {
// Find the template assigned to the product.
$productObj = ProductQuery::create()->findPk($product);
// Ignore if the product cannot be found.
if ($productObj !== null)
$template = $productObj->getTemplate();
}
// If we have to filter by template, find all attributes assigned to this template, and filter by found IDs
if (null !== $template) {
$search->filterById(
AttributeTemplateQuery::create()->filterByTemplateId($template)->select('attribute_id')->find(),
Criteria::IN
);
}
$exclude_template = $this->getExcludeTemplate();
// If we have to filter by template, find all attributes assigned to this template, and filter by found IDs
if (null !== $exclude_template) {
// Exclure tous les attribut qui sont attachés aux templates indiqués
$search->filterById(
AttributeTemplateQuery::create()->filterByTemplateId($exclude_template)->select('attribute_id')->find(),
Criteria::NOT_IN
);
$use_attribute_pos = true;
if (null !== $product) {
// Find all template assigned to the products.
$products = ProductQuery::create()->findById($product);
// Ignore if the product cannot be found.
if ($products !== null) {
// Create template array
if ($template == null) $template = array();
foreach($products as $product) {
$tpl_id = $product->getTemplateId();
if (! is_null($tpl_id)) $template[] = $tpl_id;
}
}
}
if (! empty($template)) {
// Join with feature_template table to get position
$search
->withColumn(AttributeTemplateTableMap::POSITION, 'position')
->filterByTemplate(TemplateQuery::create()->findById($template), Criteria::IN)
;
$use_attribute_pos = false;
}
else if (null !== $exclude_template) {
// Join with attribute_template table to get position
$exclude_attributes = AttributeTemplateQuery::create()->filterByTemplateId($exclude_template)->select('attribute_id')->find();
$search
->joinAttributeTemplate(null, Criteria::LEFT_JOIN)
->withColumn(AttributeTemplateTableMap::POSITION, 'position')
->filterById($exclude_attributes, Criteria::NOT_IN)
;
$use_attribute_pos = false;
}
$orders = $this->getOrder();
@@ -152,10 +170,16 @@ class Attribute extends BaseI18nLoop
$search->addDescendingOrderByColumn('i18n_TITLE');
break;
case "manual":
$search->orderByPosition(Criteria::ASC);
if ($use_attribute_pos)
$search->orderByPosition(Criteria::ASC);
else
$search->addAscendingOrderByColumn(AttributeTemplateTableMap::POSITION);
break;
case "manual_reverse":
$search->orderByPosition(Criteria::DESC);
if ($use_attribute_pos)
$search->orderByPosition(Criteria::DESC);
else
$search->addDescendingOrderByColumn(AttributeTemplateTableMap::POSITION);
break;
}
}
@@ -174,7 +198,8 @@ class Attribute extends BaseI18nLoop
->set("CHAPO", $attribute->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $attribute->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $attribute->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("POSITION", $attribute->getPosition());
->set("POSITION", $use_attribute_pos ? $attribute->getPosition() : $attribute->getVirtualColumn('position'))
;
$loopResult->addRow($loopResultRow);
}

View File

@@ -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) {

View File

@@ -41,6 +41,8 @@ use Thelia\Type\TypeCollection;
use Thelia\Type;
use Thelia\Type\BooleanOrBothType;
use Thelia\Model\FeatureTemplateQuery;
use Thelia\Model\TemplateQuery;
use Thelia\Model\Map\FeatureTemplateTableMap;
/**
*
@@ -70,7 +72,7 @@ class Feature extends BaseI18nLoop
new Argument(
'order',
new TypeCollection(
new Type\EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual_reverse'))
new Type\EnumListType(array('id', 'id_reverse', 'alpha', 'alpha-reverse', 'manual', 'manual_reverse'))
),
'manual'
),
@@ -108,39 +110,55 @@ class Feature extends BaseI18nLoop
$product = $this->getProduct();
$template = $this->getTemplate();
if (null !== $product) {
// Find the template assigned to the product.
$productObj = ProductQuery::create()->findPk($product);
// Ignore if the product cannot be found.
if ($productObj !== null)
$template = $productObj->getTemplate();
}
// If we have to filter by template, find all features assigned to this template, and filter by found IDs
if (null !== $template) {
$search->filterById(
FeatureTemplateQuery::create()->filterByTemplateId($template)->select('feature_id')->find(),
Criteria::IN
);
}
$exclude_template = $this->getExcludeTemplate();
// If we have to filter by template, find all features assigned to this template, and filter by found IDs
$use_feature_pos = true;
if (null !== $product) {
// Find all template assigned to the products.
$products = ProductQuery::create()->findById($product);
// Ignore if the product cannot be found.
if ($products !== null) {
// Create template array
if ($template == null) $template = array();
foreach($products as $product) {
$tpl_id = $product->getTemplateId();
if (! is_null($tpl_id)) $template[] = $tpl_id;
}
}
}
if (! empty($template)) {
// Join with feature_template table to get position
$search
->withColumn(FeatureTemplateTableMap::POSITION, 'position')
->filterByTemplate(TemplateQuery::create()->findById($template), Criteria::IN)
;
$use_feature_pos = false;
}
if (null !== $exclude_template) {
// Exclure tous les attribut qui sont attachés aux templates indiqués
$search->filterById(
FeatureTemplateQuery::create()->filterByTemplateId($exclude_template)->select('feature_id')->find(),
Criteria::NOT_IN
);
$exclude_features = FeatureTemplateQuery::create()->filterByTemplateId($exclude_template)->select('feature_id')->find();
$search
->joinFeatureTemplate(null, Criteria::LEFT_JOIN)
->withColumn(FeatureTemplateTableMap::POSITION, 'position')
->filterById($exclude_features, Criteria::NOT_IN)
;
$use_feature_pos = false;
}
$title = $this->getTitle();
if (null !== $title) {
//find all feture that match exactly this title and find with all locales.
//find all feature that match exactly this title and find with all locales.
$features = FeatureI18nQuery::create()
->filterByTitle($title, Criteria::LIKE)
->select('id')
@@ -158,6 +176,12 @@ class Feature extends BaseI18nLoop
foreach ($orders as $order) {
switch ($order) {
case "id":
$search->orderById(Criteria::ASC);
break;
case "id_reverse":
$search->orderById(Criteria::DESC);
break;
case "alpha":
$search->addAscendingOrderByColumn('i18n_TITLE');
break;
@@ -165,14 +189,22 @@ class Feature extends BaseI18nLoop
$search->addDescendingOrderByColumn('i18n_TITLE');
break;
case "manual":
$search->orderByPosition(Criteria::ASC);
if ($use_feature_pos)
$search->orderByPosition(Criteria::ASC);
else
$search->addAscendingOrderByColumn(FeatureTemplateTableMap::POSITION);
break;
case "manual_reverse":
$search->orderByPosition(Criteria::DESC);
if ($use_feature_pos)
$search->orderByPosition(Criteria::DESC);
else
$search->addDescendingOrderByColumn(FeatureTemplateTableMap::POSITION);
break;
}
}
/* perform search */
$features = $this->search($search, $pagination);
@@ -187,7 +219,8 @@ class Feature extends BaseI18nLoop
->set("CHAPO", $feature->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $feature->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $feature->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("POSITION", $feature->getPosition());
->set("POSITION", $use_feature_pos ? $feature->getPosition() : $feature->getVirtualColumn('position'))
;
$loopResult->addRow($loopResultRow);
}

View File

@@ -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,7 +79,7 @@ class FeatureValue extends BaseI18nLoop
{
$search = FeatureProductQuery::create();
/* manage featureAv translations */
// manage featureAv translations
$locale = $this->configureI18nProcessing(
$search,
array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'),
@@ -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();
@@ -136,17 +132,26 @@ class FeatureValue extends BaseI18nLoop
$loopResult = new LoopResult($featureValues);
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);
}

View File

@@ -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)

View File

@@ -48,8 +48,9 @@ class UrlGenerator extends AbstractSmartyPlugin
public function generateUrlFunction($params, &$smarty)
{
// the path to process
$path = $this->getParam($params, 'path', null);
$file = $this->getParam($params, 'file', null);
$path = $this->getParam($params, 'path', null);
$file = $this->getParam($params, 'file', null); // Do not invoke index.php in URL (get a static file in web space
$noamp = $this->getParam($params, 'noamp', null); // Do not change & in &amp;
if ($file !== null) {
$path = $file;
@@ -66,10 +67,12 @@ class UrlGenerator extends AbstractSmartyPlugin
$url = URL::getInstance()->absoluteUrl(
$path,
$this->getArgsFromParam($params, array('path', 'file', 'target')),
$this->getArgsFromParam($params, array('noamp', 'path', 'file', 'target')),
$mode
);
if ($noamp == null) $url = str_replace('&', '&amp;', $url);
if ($target != null) $url .= '#'.$target;
return $url;

View File

@@ -47,25 +47,48 @@ 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."),
"label" => Translator::getInstance()->trans("Default product category *"),
"label_attr" => array("for" => "default_category_field")
))
->add("locale", "text", array(
"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")
))
;
;
if (! $change_mode) {
$this->formBuilder
->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)

View File

@@ -0,0 +1,90 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Form;
use Symfony\Component\Validator\Constraints\GreaterThan;
use Thelia\Core\Translation\Translator;
use Symfony\Component\Validator\Constraints\NotBlank;
class ProductDetailsModificationForm extends BaseForm
{
use StandardDescriptionFieldsTrait;
protected function buildForm()
{
$this->formBuilder
->add("id", "integer", array(
"label" => Translator::getInstance()->trans("Prodcut ID *"),
"label_attr" => array("for" => "product_id_field"),
"constraints" => array(new GreaterThan(array('value' => 0)))
))
->add("price", "number", array(
"constraints" => array(new NotBlank()),
"label" => Translator::getInstance()->trans("Product base price excluding taxes *"),
"label_attr" => array("for" => "price_field")
))
->add("price_with_tax", "number", array(
"label" => Translator::getInstance()->trans("Product base price including taxes *"),
"label_attr" => array("for" => "price_with_tax_field")
))
->add("currency", "integer", array(
"constraints" => array(new NotBlank()),
"label" => Translator::getInstance()->trans("Price currency *"),
"label_attr" => array("for" => "currency_field")
))
->add("tax_rule", "integer", array(
"constraints" => array(new NotBlank()),
"label" => Translator::getInstance()->trans("Tax rule for this product *"),
"label_attr" => array("for" => "tax_rule_field")
))
->add("weight", "number", array(
"constraints" => array(new NotBlank()),
"label" => Translator::getInstance()->trans("Weight *"),
"label_attr" => array("for" => "weight_field")
))
->add("quantity", "number", array(
"constraints" => array(new NotBlank()),
"label" => Translator::getInstance()->trans("Current quantity *"),
"label_attr" => array("for" => "quantity_field")
))
->add("sale_price", "number", array(
"label" => Translator::getInstance()->trans("Sale price *"),
"label_attr" => array("for" => "price_with_tax_field")
))
->add("onsale", "integer", array(
"label" => Translator::getInstance()->trans("This product is on sale"),
"label_attr" => array("for" => "onsale_field")
))
->add("isnew", "integer", array(
"label" => Translator::getInstance()->trans("Advertise this product as new"),
"label_attr" => array("for" => "isnew_field")
))
;
}
public function getName()
{
return "thelia_product_details_modification";
}
}

View File

@@ -3,8 +3,29 @@
namespace Thelia\Model;
use Thelia\Model\Base\AttributeTemplate as BaseAttributeTemplate;
use Propel\Runtime\Connection\ConnectionInterface;
class AttributeTemplate extends BaseAttributeTemplate
class AttributeTemplate extends BaseAttributeTemplate
{
use \Thelia\Model\Tools\ModelEventDispatcherTrait;
use \Thelia\Model\Tools\PositionManagementTrait;
/**
* Calculate next position relative to our template
*/
protected function addCriteriaToPositionQuery($query)
{
$query->filterByTemplateId($this->getTemplateId());
}
/**
* {@inheritDoc}
*/
public function preInsert(ConnectionInterface $con = null)
{
$this->setPosition($this->getNextPosition());
return true;
}
}

View File

@@ -76,6 +76,18 @@ abstract class AttributeTemplate implements ActiveRecordInterface
*/
protected $template_id;
/**
* The value for the position field.
* @var int
*/
protected $position;
/**
* The value for the attribute_templatecol field.
* @var string
*/
protected $attribute_templatecol;
/**
* The value for the created_at field.
* @var string
@@ -393,6 +405,28 @@ abstract class AttributeTemplate implements ActiveRecordInterface
return $this->template_id;
}
/**
* Get the [position] column value.
*
* @return int
*/
public function getPosition()
{
return $this->position;
}
/**
* Get the [attribute_templatecol] column value.
*
* @return string
*/
public function getAttributeTemplatecol()
{
return $this->attribute_templatecol;
}
/**
* Get the [optionally formatted] temporal [created_at] column value.
*
@@ -504,6 +538,48 @@ abstract class AttributeTemplate implements ActiveRecordInterface
return $this;
} // setTemplateId()
/**
* Set the value of [position] column.
*
* @param int $v new value
* @return \Thelia\Model\AttributeTemplate The current object (for fluent API support)
*/
public function setPosition($v)
{
if ($v !== null) {
$v = (int) $v;
}
if ($this->position !== $v) {
$this->position = $v;
$this->modifiedColumns[] = AttributeTemplateTableMap::POSITION;
}
return $this;
} // setPosition()
/**
* Set the value of [attribute_templatecol] column.
*
* @param string $v new value
* @return \Thelia\Model\AttributeTemplate The current object (for fluent API support)
*/
public function setAttributeTemplatecol($v)
{
if ($v !== null) {
$v = (string) $v;
}
if ($this->attribute_templatecol !== $v) {
$this->attribute_templatecol = $v;
$this->modifiedColumns[] = AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL;
}
return $this;
} // setAttributeTemplatecol()
/**
* Sets the value of [created_at] column to a normalized version of the date/time value specified.
*
@@ -592,13 +668,19 @@ abstract class AttributeTemplate implements ActiveRecordInterface
$col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : AttributeTemplateTableMap::translateFieldName('TemplateId', TableMap::TYPE_PHPNAME, $indexType)];
$this->template_id = (null !== $col) ? (int) $col : null;
$col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : AttributeTemplateTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)];
$col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : AttributeTemplateTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)];
$this->position = (null !== $col) ? (int) $col : null;
$col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : AttributeTemplateTableMap::translateFieldName('AttributeTemplatecol', TableMap::TYPE_PHPNAME, $indexType)];
$this->attribute_templatecol = (null !== $col) ? (string) $col : null;
$col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : AttributeTemplateTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)];
if ($col === '0000-00-00 00:00:00') {
$col = null;
}
$this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null;
$col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : AttributeTemplateTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)];
$col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : AttributeTemplateTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)];
if ($col === '0000-00-00 00:00:00') {
$col = null;
}
@@ -611,7 +693,7 @@ abstract class AttributeTemplate implements ActiveRecordInterface
$this->ensureConsistency();
}
return $startcol + 5; // 5 = AttributeTemplateTableMap::NUM_HYDRATE_COLUMNS.
return $startcol + 7; // 7 = AttributeTemplateTableMap::NUM_HYDRATE_COLUMNS.
} catch (Exception $e) {
throw new PropelException("Error populating \Thelia\Model\AttributeTemplate object", 0, $e);
@@ -867,6 +949,12 @@ abstract class AttributeTemplate implements ActiveRecordInterface
if ($this->isColumnModified(AttributeTemplateTableMap::TEMPLATE_ID)) {
$modifiedColumns[':p' . $index++] = 'TEMPLATE_ID';
}
if ($this->isColumnModified(AttributeTemplateTableMap::POSITION)) {
$modifiedColumns[':p' . $index++] = 'POSITION';
}
if ($this->isColumnModified(AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL)) {
$modifiedColumns[':p' . $index++] = 'ATTRIBUTE_TEMPLATECOL';
}
if ($this->isColumnModified(AttributeTemplateTableMap::CREATED_AT)) {
$modifiedColumns[':p' . $index++] = 'CREATED_AT';
}
@@ -893,6 +981,12 @@ abstract class AttributeTemplate implements ActiveRecordInterface
case 'TEMPLATE_ID':
$stmt->bindValue($identifier, $this->template_id, PDO::PARAM_INT);
break;
case 'POSITION':
$stmt->bindValue($identifier, $this->position, PDO::PARAM_INT);
break;
case 'ATTRIBUTE_TEMPLATECOL':
$stmt->bindValue($identifier, $this->attribute_templatecol, 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;
@@ -971,9 +1065,15 @@ abstract class AttributeTemplate implements ActiveRecordInterface
return $this->getTemplateId();
break;
case 3:
return $this->getCreatedAt();
return $this->getPosition();
break;
case 4:
return $this->getAttributeTemplatecol();
break;
case 5:
return $this->getCreatedAt();
break;
case 6:
return $this->getUpdatedAt();
break;
default:
@@ -1008,8 +1108,10 @@ abstract class AttributeTemplate implements ActiveRecordInterface
$keys[0] => $this->getId(),
$keys[1] => $this->getAttributeId(),
$keys[2] => $this->getTemplateId(),
$keys[3] => $this->getCreatedAt(),
$keys[4] => $this->getUpdatedAt(),
$keys[3] => $this->getPosition(),
$keys[4] => $this->getAttributeTemplatecol(),
$keys[5] => $this->getCreatedAt(),
$keys[6] => $this->getUpdatedAt(),
);
$virtualColumns = $this->virtualColumns;
foreach($virtualColumns as $key => $virtualColumn)
@@ -1068,9 +1170,15 @@ abstract class AttributeTemplate implements ActiveRecordInterface
$this->setTemplateId($value);
break;
case 3:
$this->setCreatedAt($value);
$this->setPosition($value);
break;
case 4:
$this->setAttributeTemplatecol($value);
break;
case 5:
$this->setCreatedAt($value);
break;
case 6:
$this->setUpdatedAt($value);
break;
} // switch()
@@ -1100,8 +1208,10 @@ abstract class AttributeTemplate implements ActiveRecordInterface
if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]);
if (array_key_exists($keys[1], $arr)) $this->setAttributeId($arr[$keys[1]]);
if (array_key_exists($keys[2], $arr)) $this->setTemplateId($arr[$keys[2]]);
if (array_key_exists($keys[3], $arr)) $this->setCreatedAt($arr[$keys[3]]);
if (array_key_exists($keys[4], $arr)) $this->setUpdatedAt($arr[$keys[4]]);
if (array_key_exists($keys[3], $arr)) $this->setPosition($arr[$keys[3]]);
if (array_key_exists($keys[4], $arr)) $this->setAttributeTemplatecol($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]]);
}
/**
@@ -1116,6 +1226,8 @@ abstract class AttributeTemplate implements ActiveRecordInterface
if ($this->isColumnModified(AttributeTemplateTableMap::ID)) $criteria->add(AttributeTemplateTableMap::ID, $this->id);
if ($this->isColumnModified(AttributeTemplateTableMap::ATTRIBUTE_ID)) $criteria->add(AttributeTemplateTableMap::ATTRIBUTE_ID, $this->attribute_id);
if ($this->isColumnModified(AttributeTemplateTableMap::TEMPLATE_ID)) $criteria->add(AttributeTemplateTableMap::TEMPLATE_ID, $this->template_id);
if ($this->isColumnModified(AttributeTemplateTableMap::POSITION)) $criteria->add(AttributeTemplateTableMap::POSITION, $this->position);
if ($this->isColumnModified(AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL)) $criteria->add(AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL, $this->attribute_templatecol);
if ($this->isColumnModified(AttributeTemplateTableMap::CREATED_AT)) $criteria->add(AttributeTemplateTableMap::CREATED_AT, $this->created_at);
if ($this->isColumnModified(AttributeTemplateTableMap::UPDATED_AT)) $criteria->add(AttributeTemplateTableMap::UPDATED_AT, $this->updated_at);
@@ -1183,6 +1295,8 @@ abstract class AttributeTemplate implements ActiveRecordInterface
{
$copyObj->setAttributeId($this->getAttributeId());
$copyObj->setTemplateId($this->getTemplateId());
$copyObj->setPosition($this->getPosition());
$copyObj->setAttributeTemplatecol($this->getAttributeTemplatecol());
$copyObj->setCreatedAt($this->getCreatedAt());
$copyObj->setUpdatedAt($this->getUpdatedAt());
if ($makeNew) {
@@ -1323,6 +1437,8 @@ abstract class AttributeTemplate implements ActiveRecordInterface
$this->id = null;
$this->attribute_id = null;
$this->template_id = null;
$this->position = null;
$this->attribute_templatecol = null;
$this->created_at = null;
$this->updated_at = null;
$this->alreadyInSave = false;

View File

@@ -24,12 +24,16 @@ use Thelia\Model\Map\AttributeTemplateTableMap;
* @method ChildAttributeTemplateQuery orderById($order = Criteria::ASC) Order by the id column
* @method ChildAttributeTemplateQuery orderByAttributeId($order = Criteria::ASC) Order by the attribute_id column
* @method ChildAttributeTemplateQuery orderByTemplateId($order = Criteria::ASC) Order by the template_id column
* @method ChildAttributeTemplateQuery orderByPosition($order = Criteria::ASC) Order by the position column
* @method ChildAttributeTemplateQuery orderByAttributeTemplatecol($order = Criteria::ASC) Order by the attribute_templatecol column
* @method ChildAttributeTemplateQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column
* @method ChildAttributeTemplateQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column
*
* @method ChildAttributeTemplateQuery groupById() Group by the id column
* @method ChildAttributeTemplateQuery groupByAttributeId() Group by the attribute_id column
* @method ChildAttributeTemplateQuery groupByTemplateId() Group by the template_id column
* @method ChildAttributeTemplateQuery groupByPosition() Group by the position column
* @method ChildAttributeTemplateQuery groupByAttributeTemplatecol() Group by the attribute_templatecol column
* @method ChildAttributeTemplateQuery groupByCreatedAt() Group by the created_at column
* @method ChildAttributeTemplateQuery groupByUpdatedAt() Group by the updated_at column
*
@@ -51,12 +55,16 @@ use Thelia\Model\Map\AttributeTemplateTableMap;
* @method ChildAttributeTemplate findOneById(int $id) Return the first ChildAttributeTemplate filtered by the id column
* @method ChildAttributeTemplate findOneByAttributeId(int $attribute_id) Return the first ChildAttributeTemplate filtered by the attribute_id column
* @method ChildAttributeTemplate findOneByTemplateId(int $template_id) Return the first ChildAttributeTemplate filtered by the template_id column
* @method ChildAttributeTemplate findOneByPosition(int $position) Return the first ChildAttributeTemplate filtered by the position column
* @method ChildAttributeTemplate findOneByAttributeTemplatecol(string $attribute_templatecol) Return the first ChildAttributeTemplate filtered by the attribute_templatecol column
* @method ChildAttributeTemplate findOneByCreatedAt(string $created_at) Return the first ChildAttributeTemplate filtered by the created_at column
* @method ChildAttributeTemplate findOneByUpdatedAt(string $updated_at) Return the first ChildAttributeTemplate filtered by the updated_at column
*
* @method array findById(int $id) Return ChildAttributeTemplate objects filtered by the id column
* @method array findByAttributeId(int $attribute_id) Return ChildAttributeTemplate objects filtered by the attribute_id column
* @method array findByTemplateId(int $template_id) Return ChildAttributeTemplate objects filtered by the template_id column
* @method array findByPosition(int $position) Return ChildAttributeTemplate objects filtered by the position column
* @method array findByAttributeTemplatecol(string $attribute_templatecol) Return ChildAttributeTemplate objects filtered by the attribute_templatecol column
* @method array findByCreatedAt(string $created_at) Return ChildAttributeTemplate objects filtered by the created_at column
* @method array findByUpdatedAt(string $updated_at) Return ChildAttributeTemplate objects filtered by the updated_at column
*
@@ -147,7 +155,7 @@ abstract class AttributeTemplateQuery extends ModelCriteria
*/
protected function findPkSimple($key, $con)
{
$sql = 'SELECT ID, ATTRIBUTE_ID, TEMPLATE_ID, CREATED_AT, UPDATED_AT FROM attribute_template WHERE ID = :p0';
$sql = 'SELECT ID, ATTRIBUTE_ID, TEMPLATE_ID, POSITION, ATTRIBUTE_TEMPLATECOL, CREATED_AT, UPDATED_AT FROM attribute_template WHERE ID = :p0';
try {
$stmt = $con->prepare($sql);
$stmt->bindValue(':p0', $key, PDO::PARAM_INT);
@@ -363,6 +371,76 @@ abstract class AttributeTemplateQuery extends ModelCriteria
return $this->addUsingAlias(AttributeTemplateTableMap::TEMPLATE_ID, $templateId, $comparison);
}
/**
* Filter the query on the position column
*
* Example usage:
* <code>
* $query->filterByPosition(1234); // WHERE position = 1234
* $query->filterByPosition(array(12, 34)); // WHERE position IN (12, 34)
* $query->filterByPosition(array('min' => 12)); // WHERE position > 12
* </code>
*
* @param mixed $position The value to use as filter.
* Use scalar values for equality.
* Use array values for in_array() equivalent.
* Use associative array('min' => $minValue, 'max' => $maxValue) for intervals.
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return ChildAttributeTemplateQuery The current query, for fluid interface
*/
public function filterByPosition($position = null, $comparison = null)
{
if (is_array($position)) {
$useMinMax = false;
if (isset($position['min'])) {
$this->addUsingAlias(AttributeTemplateTableMap::POSITION, $position['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($position['max'])) {
$this->addUsingAlias(AttributeTemplateTableMap::POSITION, $position['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN;
}
}
return $this->addUsingAlias(AttributeTemplateTableMap::POSITION, $position, $comparison);
}
/**
* Filter the query on the attribute_templatecol column
*
* Example usage:
* <code>
* $query->filterByAttributeTemplatecol('fooValue'); // WHERE attribute_templatecol = 'fooValue'
* $query->filterByAttributeTemplatecol('%fooValue%'); // WHERE attribute_templatecol LIKE '%fooValue%'
* </code>
*
* @param string $attributeTemplatecol 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 ChildAttributeTemplateQuery The current query, for fluid interface
*/
public function filterByAttributeTemplatecol($attributeTemplatecol = null, $comparison = null)
{
if (null === $comparison) {
if (is_array($attributeTemplatecol)) {
$comparison = Criteria::IN;
} elseif (preg_match('/[\%\*]/', $attributeTemplatecol)) {
$attributeTemplatecol = str_replace('*', '%', $attributeTemplatecol);
$comparison = Criteria::LIKE;
}
}
return $this->addUsingAlias(AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL, $attributeTemplatecol, $comparison);
}
/**
* Filter the query on the created_at column
*

View File

@@ -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;

View File

@@ -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:
* <code>
* $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%'
* </code>
*
* @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);
}
/**

View File

@@ -76,6 +76,12 @@ abstract class FeatureTemplate implements ActiveRecordInterface
*/
protected $template_id;
/**
* The value for the position field.
* @var int
*/
protected $position;
/**
* The value for the created_at field.
* @var string
@@ -393,6 +399,17 @@ abstract class FeatureTemplate implements ActiveRecordInterface
return $this->template_id;
}
/**
* Get the [position] column value.
*
* @return int
*/
public function getPosition()
{
return $this->position;
}
/**
* Get the [optionally formatted] temporal [created_at] column value.
*
@@ -504,6 +521,27 @@ abstract class FeatureTemplate implements ActiveRecordInterface
return $this;
} // setTemplateId()
/**
* Set the value of [position] column.
*
* @param int $v new value
* @return \Thelia\Model\FeatureTemplate The current object (for fluent API support)
*/
public function setPosition($v)
{
if ($v !== null) {
$v = (int) $v;
}
if ($this->position !== $v) {
$this->position = $v;
$this->modifiedColumns[] = FeatureTemplateTableMap::POSITION;
}
return $this;
} // setPosition()
/**
* Sets the value of [created_at] column to a normalized version of the date/time value specified.
*
@@ -592,13 +630,16 @@ abstract class FeatureTemplate implements ActiveRecordInterface
$col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : FeatureTemplateTableMap::translateFieldName('TemplateId', TableMap::TYPE_PHPNAME, $indexType)];
$this->template_id = (null !== $col) ? (int) $col : null;
$col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : FeatureTemplateTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)];
$col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : FeatureTemplateTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)];
$this->position = (null !== $col) ? (int) $col : null;
$col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : FeatureTemplateTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)];
if ($col === '0000-00-00 00:00:00') {
$col = null;
}
$this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null;
$col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : FeatureTemplateTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)];
$col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : FeatureTemplateTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)];
if ($col === '0000-00-00 00:00:00') {
$col = null;
}
@@ -611,7 +652,7 @@ abstract class FeatureTemplate implements ActiveRecordInterface
$this->ensureConsistency();
}
return $startcol + 5; // 5 = FeatureTemplateTableMap::NUM_HYDRATE_COLUMNS.
return $startcol + 6; // 6 = FeatureTemplateTableMap::NUM_HYDRATE_COLUMNS.
} catch (Exception $e) {
throw new PropelException("Error populating \Thelia\Model\FeatureTemplate object", 0, $e);
@@ -867,6 +908,9 @@ abstract class FeatureTemplate implements ActiveRecordInterface
if ($this->isColumnModified(FeatureTemplateTableMap::TEMPLATE_ID)) {
$modifiedColumns[':p' . $index++] = 'TEMPLATE_ID';
}
if ($this->isColumnModified(FeatureTemplateTableMap::POSITION)) {
$modifiedColumns[':p' . $index++] = 'POSITION';
}
if ($this->isColumnModified(FeatureTemplateTableMap::CREATED_AT)) {
$modifiedColumns[':p' . $index++] = 'CREATED_AT';
}
@@ -893,6 +937,9 @@ abstract class FeatureTemplate implements ActiveRecordInterface
case 'TEMPLATE_ID':
$stmt->bindValue($identifier, $this->template_id, PDO::PARAM_INT);
break;
case 'POSITION':
$stmt->bindValue($identifier, $this->position, 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;
@@ -971,9 +1018,12 @@ abstract class FeatureTemplate implements ActiveRecordInterface
return $this->getTemplateId();
break;
case 3:
return $this->getCreatedAt();
return $this->getPosition();
break;
case 4:
return $this->getCreatedAt();
break;
case 5:
return $this->getUpdatedAt();
break;
default:
@@ -1008,8 +1058,9 @@ abstract class FeatureTemplate implements ActiveRecordInterface
$keys[0] => $this->getId(),
$keys[1] => $this->getFeatureId(),
$keys[2] => $this->getTemplateId(),
$keys[3] => $this->getCreatedAt(),
$keys[4] => $this->getUpdatedAt(),
$keys[3] => $this->getPosition(),
$keys[4] => $this->getCreatedAt(),
$keys[5] => $this->getUpdatedAt(),
);
$virtualColumns = $this->virtualColumns;
foreach($virtualColumns as $key => $virtualColumn)
@@ -1068,9 +1119,12 @@ abstract class FeatureTemplate implements ActiveRecordInterface
$this->setTemplateId($value);
break;
case 3:
$this->setCreatedAt($value);
$this->setPosition($value);
break;
case 4:
$this->setCreatedAt($value);
break;
case 5:
$this->setUpdatedAt($value);
break;
} // switch()
@@ -1100,8 +1154,9 @@ abstract class FeatureTemplate implements ActiveRecordInterface
if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]);
if (array_key_exists($keys[1], $arr)) $this->setFeatureId($arr[$keys[1]]);
if (array_key_exists($keys[2], $arr)) $this->setTemplateId($arr[$keys[2]]);
if (array_key_exists($keys[3], $arr)) $this->setCreatedAt($arr[$keys[3]]);
if (array_key_exists($keys[4], $arr)) $this->setUpdatedAt($arr[$keys[4]]);
if (array_key_exists($keys[3], $arr)) $this->setPosition($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]]);
}
/**
@@ -1116,6 +1171,7 @@ abstract class FeatureTemplate implements ActiveRecordInterface
if ($this->isColumnModified(FeatureTemplateTableMap::ID)) $criteria->add(FeatureTemplateTableMap::ID, $this->id);
if ($this->isColumnModified(FeatureTemplateTableMap::FEATURE_ID)) $criteria->add(FeatureTemplateTableMap::FEATURE_ID, $this->feature_id);
if ($this->isColumnModified(FeatureTemplateTableMap::TEMPLATE_ID)) $criteria->add(FeatureTemplateTableMap::TEMPLATE_ID, $this->template_id);
if ($this->isColumnModified(FeatureTemplateTableMap::POSITION)) $criteria->add(FeatureTemplateTableMap::POSITION, $this->position);
if ($this->isColumnModified(FeatureTemplateTableMap::CREATED_AT)) $criteria->add(FeatureTemplateTableMap::CREATED_AT, $this->created_at);
if ($this->isColumnModified(FeatureTemplateTableMap::UPDATED_AT)) $criteria->add(FeatureTemplateTableMap::UPDATED_AT, $this->updated_at);
@@ -1183,6 +1239,7 @@ abstract class FeatureTemplate implements ActiveRecordInterface
{
$copyObj->setFeatureId($this->getFeatureId());
$copyObj->setTemplateId($this->getTemplateId());
$copyObj->setPosition($this->getPosition());
$copyObj->setCreatedAt($this->getCreatedAt());
$copyObj->setUpdatedAt($this->getUpdatedAt());
if ($makeNew) {
@@ -1323,6 +1380,7 @@ abstract class FeatureTemplate implements ActiveRecordInterface
$this->id = null;
$this->feature_id = null;
$this->template_id = null;
$this->position = null;
$this->created_at = null;
$this->updated_at = null;
$this->alreadyInSave = false;

View File

@@ -24,12 +24,14 @@ use Thelia\Model\Map\FeatureTemplateTableMap;
* @method ChildFeatureTemplateQuery orderById($order = Criteria::ASC) Order by the id column
* @method ChildFeatureTemplateQuery orderByFeatureId($order = Criteria::ASC) Order by the feature_id column
* @method ChildFeatureTemplateQuery orderByTemplateId($order = Criteria::ASC) Order by the template_id column
* @method ChildFeatureTemplateQuery orderByPosition($order = Criteria::ASC) Order by the position column
* @method ChildFeatureTemplateQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column
* @method ChildFeatureTemplateQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column
*
* @method ChildFeatureTemplateQuery groupById() Group by the id column
* @method ChildFeatureTemplateQuery groupByFeatureId() Group by the feature_id column
* @method ChildFeatureTemplateQuery groupByTemplateId() Group by the template_id column
* @method ChildFeatureTemplateQuery groupByPosition() Group by the position column
* @method ChildFeatureTemplateQuery groupByCreatedAt() Group by the created_at column
* @method ChildFeatureTemplateQuery groupByUpdatedAt() Group by the updated_at column
*
@@ -51,12 +53,14 @@ use Thelia\Model\Map\FeatureTemplateTableMap;
* @method ChildFeatureTemplate findOneById(int $id) Return the first ChildFeatureTemplate filtered by the id column
* @method ChildFeatureTemplate findOneByFeatureId(int $feature_id) Return the first ChildFeatureTemplate filtered by the feature_id column
* @method ChildFeatureTemplate findOneByTemplateId(int $template_id) Return the first ChildFeatureTemplate filtered by the template_id column
* @method ChildFeatureTemplate findOneByPosition(int $position) Return the first ChildFeatureTemplate filtered by the position column
* @method ChildFeatureTemplate findOneByCreatedAt(string $created_at) Return the first ChildFeatureTemplate filtered by the created_at column
* @method ChildFeatureTemplate findOneByUpdatedAt(string $updated_at) Return the first ChildFeatureTemplate filtered by the updated_at column
*
* @method array findById(int $id) Return ChildFeatureTemplate objects filtered by the id column
* @method array findByFeatureId(int $feature_id) Return ChildFeatureTemplate objects filtered by the feature_id column
* @method array findByTemplateId(int $template_id) Return ChildFeatureTemplate objects filtered by the template_id column
* @method array findByPosition(int $position) Return ChildFeatureTemplate objects filtered by the position column
* @method array findByCreatedAt(string $created_at) Return ChildFeatureTemplate objects filtered by the created_at column
* @method array findByUpdatedAt(string $updated_at) Return ChildFeatureTemplate objects filtered by the updated_at column
*
@@ -147,7 +151,7 @@ abstract class FeatureTemplateQuery extends ModelCriteria
*/
protected function findPkSimple($key, $con)
{
$sql = 'SELECT ID, FEATURE_ID, TEMPLATE_ID, CREATED_AT, UPDATED_AT FROM feature_template WHERE ID = :p0';
$sql = 'SELECT ID, FEATURE_ID, TEMPLATE_ID, POSITION, CREATED_AT, UPDATED_AT FROM feature_template WHERE ID = :p0';
try {
$stmt = $con->prepare($sql);
$stmt->bindValue(':p0', $key, PDO::PARAM_INT);
@@ -363,6 +367,47 @@ abstract class FeatureTemplateQuery extends ModelCriteria
return $this->addUsingAlias(FeatureTemplateTableMap::TEMPLATE_ID, $templateId, $comparison);
}
/**
* Filter the query on the position column
*
* Example usage:
* <code>
* $query->filterByPosition(1234); // WHERE position = 1234
* $query->filterByPosition(array(12, 34)); // WHERE position IN (12, 34)
* $query->filterByPosition(array('min' => 12)); // WHERE position > 12
* </code>
*
* @param mixed $position The value to use as filter.
* Use scalar values for equality.
* Use array values for in_array() equivalent.
* Use associative array('min' => $minValue, 'max' => $maxValue) for intervals.
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return ChildFeatureTemplateQuery The current query, for fluid interface
*/
public function filterByPosition($position = null, $comparison = null)
{
if (is_array($position)) {
$useMinMax = false;
if (isset($position['min'])) {
$this->addUsingAlias(FeatureTemplateTableMap::POSITION, $position['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($position['max'])) {
$this->addUsingAlias(FeatureTemplateTableMap::POSITION, $position['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN;
}
}
return $this->addUsingAlias(FeatureTemplateTableMap::POSITION, $position, $comparison);
}
/**
* Filter the query on the created_at column
*

View File

@@ -103,10 +103,18 @@ abstract class ProductSaleElements implements ActiveRecordInterface
/**
* The value for the weight field.
* Note: this column has a database default value of: 0
* @var double
*/
protected $weight;
/**
* 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
@@ -178,6 +186,8 @@ abstract class ProductSaleElements implements ActiveRecordInterface
{
$this->promo = 0;
$this->newness = 0;
$this->weight = 0;
$this->is_default = false;
}
/**
@@ -513,6 +523,17 @@ abstract class ProductSaleElements implements ActiveRecordInterface
return $this->weight;
}
/**
* Get the [is_default] column value.
*
* @return boolean
*/
public function getIsDefault()
{
return $this->is_default;
}
/**
* Get the [optionally formatted] temporal [created_at] column value.
*
@@ -704,6 +725,35 @@ abstract class ProductSaleElements implements ActiveRecordInterface
return $this;
} // setWeight()
/**
* 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\ProductSaleElements 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[] = ProductSaleElementsTableMap::IS_DEFAULT;
}
return $this;
} // setIsDefault()
/**
* Sets the value of [created_at] column to a normalized version of the date/time value specified.
*
@@ -764,6 +814,14 @@ abstract class ProductSaleElements implements ActiveRecordInterface
return false;
}
if ($this->weight !== 0) {
return false;
}
if ($this->is_default !== false) {
return false;
}
// otherwise, everything was equal, so return TRUE
return true;
} // hasOnlyDefaultValues()
@@ -812,13 +870,16 @@ abstract class ProductSaleElements implements ActiveRecordInterface
$col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : ProductSaleElementsTableMap::translateFieldName('Weight', TableMap::TYPE_PHPNAME, $indexType)];
$this->weight = (null !== $col) ? (double) $col : null;
$col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : ProductSaleElementsTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)];
$col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : ProductSaleElementsTableMap::translateFieldName('IsDefault', TableMap::TYPE_PHPNAME, $indexType)];
$this->is_default = (null !== $col) ? (boolean) $col : null;
$col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : ProductSaleElementsTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)];
if ($col === '0000-00-00 00:00:00') {
$col = null;
}
$this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null;
$col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : ProductSaleElementsTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)];
$col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : ProductSaleElementsTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)];
if ($col === '0000-00-00 00:00:00') {
$col = null;
}
@@ -831,7 +892,7 @@ abstract class ProductSaleElements implements ActiveRecordInterface
$this->ensureConsistency();
}
return $startcol + 9; // 9 = ProductSaleElementsTableMap::NUM_HYDRATE_COLUMNS.
return $startcol + 10; // 10 = ProductSaleElementsTableMap::NUM_HYDRATE_COLUMNS.
} catch (Exception $e) {
throw new PropelException("Error populating \Thelia\Model\ProductSaleElements object", 0, $e);
@@ -1145,6 +1206,9 @@ abstract class ProductSaleElements implements ActiveRecordInterface
if ($this->isColumnModified(ProductSaleElementsTableMap::WEIGHT)) {
$modifiedColumns[':p' . $index++] = 'WEIGHT';
}
if ($this->isColumnModified(ProductSaleElementsTableMap::IS_DEFAULT)) {
$modifiedColumns[':p' . $index++] = 'IS_DEFAULT';
}
if ($this->isColumnModified(ProductSaleElementsTableMap::CREATED_AT)) {
$modifiedColumns[':p' . $index++] = 'CREATED_AT';
}
@@ -1183,6 +1247,9 @@ abstract class ProductSaleElements implements ActiveRecordInterface
case 'WEIGHT':
$stmt->bindValue($identifier, $this->weight, PDO::PARAM_STR);
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;
@@ -1273,9 +1340,12 @@ abstract class ProductSaleElements implements ActiveRecordInterface
return $this->getWeight();
break;
case 7:
return $this->getCreatedAt();
return $this->getIsDefault();
break;
case 8:
return $this->getCreatedAt();
break;
case 9:
return $this->getUpdatedAt();
break;
default:
@@ -1314,8 +1384,9 @@ abstract class ProductSaleElements implements ActiveRecordInterface
$keys[4] => $this->getPromo(),
$keys[5] => $this->getNewness(),
$keys[6] => $this->getWeight(),
$keys[7] => $this->getCreatedAt(),
$keys[8] => $this->getUpdatedAt(),
$keys[7] => $this->getIsDefault(),
$keys[8] => $this->getCreatedAt(),
$keys[9] => $this->getUpdatedAt(),
);
$virtualColumns = $this->virtualColumns;
foreach($virtualColumns as $key => $virtualColumn)
@@ -1392,9 +1463,12 @@ abstract class ProductSaleElements implements ActiveRecordInterface
$this->setWeight($value);
break;
case 7:
$this->setCreatedAt($value);
$this->setIsDefault($value);
break;
case 8:
$this->setCreatedAt($value);
break;
case 9:
$this->setUpdatedAt($value);
break;
} // switch()
@@ -1428,8 +1502,9 @@ abstract class ProductSaleElements implements ActiveRecordInterface
if (array_key_exists($keys[4], $arr)) $this->setPromo($arr[$keys[4]]);
if (array_key_exists($keys[5], $arr)) $this->setNewness($arr[$keys[5]]);
if (array_key_exists($keys[6], $arr)) $this->setWeight($arr[$keys[6]]);
if (array_key_exists($keys[7], $arr)) $this->setCreatedAt($arr[$keys[7]]);
if (array_key_exists($keys[8], $arr)) $this->setUpdatedAt($arr[$keys[8]]);
if (array_key_exists($keys[7], $arr)) $this->setIsDefault($arr[$keys[7]]);
if (array_key_exists($keys[8], $arr)) $this->setCreatedAt($arr[$keys[8]]);
if (array_key_exists($keys[9], $arr)) $this->setUpdatedAt($arr[$keys[9]]);
}
/**
@@ -1448,6 +1523,7 @@ abstract class ProductSaleElements implements ActiveRecordInterface
if ($this->isColumnModified(ProductSaleElementsTableMap::PROMO)) $criteria->add(ProductSaleElementsTableMap::PROMO, $this->promo);
if ($this->isColumnModified(ProductSaleElementsTableMap::NEWNESS)) $criteria->add(ProductSaleElementsTableMap::NEWNESS, $this->newness);
if ($this->isColumnModified(ProductSaleElementsTableMap::WEIGHT)) $criteria->add(ProductSaleElementsTableMap::WEIGHT, $this->weight);
if ($this->isColumnModified(ProductSaleElementsTableMap::IS_DEFAULT)) $criteria->add(ProductSaleElementsTableMap::IS_DEFAULT, $this->is_default);
if ($this->isColumnModified(ProductSaleElementsTableMap::CREATED_AT)) $criteria->add(ProductSaleElementsTableMap::CREATED_AT, $this->created_at);
if ($this->isColumnModified(ProductSaleElementsTableMap::UPDATED_AT)) $criteria->add(ProductSaleElementsTableMap::UPDATED_AT, $this->updated_at);
@@ -1519,6 +1595,7 @@ abstract class ProductSaleElements implements ActiveRecordInterface
$copyObj->setPromo($this->getPromo());
$copyObj->setNewness($this->getNewness());
$copyObj->setWeight($this->getWeight());
$copyObj->setIsDefault($this->getIsDefault());
$copyObj->setCreatedAt($this->getCreatedAt());
$copyObj->setUpdatedAt($this->getUpdatedAt());
@@ -2445,6 +2522,7 @@ abstract class ProductSaleElements implements ActiveRecordInterface
$this->promo = null;
$this->newness = null;
$this->weight = null;
$this->is_default = null;
$this->created_at = null;
$this->updated_at = null;
$this->alreadyInSave = false;

View File

@@ -28,6 +28,7 @@ use Thelia\Model\Map\ProductSaleElementsTableMap;
* @method ChildProductSaleElementsQuery orderByPromo($order = Criteria::ASC) Order by the promo column
* @method ChildProductSaleElementsQuery orderByNewness($order = Criteria::ASC) Order by the newness column
* @method ChildProductSaleElementsQuery orderByWeight($order = Criteria::ASC) Order by the weight column
* @method ChildProductSaleElementsQuery orderByIsDefault($order = Criteria::ASC) Order by the is_default column
* @method ChildProductSaleElementsQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column
* @method ChildProductSaleElementsQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column
*
@@ -38,6 +39,7 @@ use Thelia\Model\Map\ProductSaleElementsTableMap;
* @method ChildProductSaleElementsQuery groupByPromo() Group by the promo column
* @method ChildProductSaleElementsQuery groupByNewness() Group by the newness column
* @method ChildProductSaleElementsQuery groupByWeight() Group by the weight column
* @method ChildProductSaleElementsQuery groupByIsDefault() Group by the is_default column
* @method ChildProductSaleElementsQuery groupByCreatedAt() Group by the created_at column
* @method ChildProductSaleElementsQuery groupByUpdatedAt() Group by the updated_at column
*
@@ -71,6 +73,7 @@ use Thelia\Model\Map\ProductSaleElementsTableMap;
* @method ChildProductSaleElements findOneByPromo(int $promo) Return the first ChildProductSaleElements filtered by the promo column
* @method ChildProductSaleElements findOneByNewness(int $newness) Return the first ChildProductSaleElements filtered by the newness column
* @method ChildProductSaleElements findOneByWeight(double $weight) Return the first ChildProductSaleElements filtered by the weight column
* @method ChildProductSaleElements findOneByIsDefault(boolean $is_default) Return the first ChildProductSaleElements filtered by the is_default column
* @method ChildProductSaleElements findOneByCreatedAt(string $created_at) Return the first ChildProductSaleElements filtered by the created_at column
* @method ChildProductSaleElements findOneByUpdatedAt(string $updated_at) Return the first ChildProductSaleElements filtered by the updated_at column
*
@@ -81,6 +84,7 @@ use Thelia\Model\Map\ProductSaleElementsTableMap;
* @method array findByPromo(int $promo) Return ChildProductSaleElements objects filtered by the promo column
* @method array findByNewness(int $newness) Return ChildProductSaleElements objects filtered by the newness column
* @method array findByWeight(double $weight) Return ChildProductSaleElements objects filtered by the weight column
* @method array findByIsDefault(boolean $is_default) Return ChildProductSaleElements objects filtered by the is_default column
* @method array findByCreatedAt(string $created_at) Return ChildProductSaleElements objects filtered by the created_at column
* @method array findByUpdatedAt(string $updated_at) Return ChildProductSaleElements objects filtered by the updated_at column
*
@@ -171,7 +175,7 @@ abstract class ProductSaleElementsQuery extends ModelCriteria
*/
protected function findPkSimple($key, $con)
{
$sql = 'SELECT ID, PRODUCT_ID, REF, QUANTITY, PROMO, NEWNESS, WEIGHT, CREATED_AT, UPDATED_AT FROM product_sale_elements WHERE ID = :p0';
$sql = 'SELECT ID, PRODUCT_ID, REF, QUANTITY, PROMO, NEWNESS, WEIGHT, IS_DEFAULT, CREATED_AT, UPDATED_AT FROM product_sale_elements WHERE ID = :p0';
try {
$stmt = $con->prepare($sql);
$stmt->bindValue(':p0', $key, PDO::PARAM_INT);
@@ -537,6 +541,33 @@ abstract class ProductSaleElementsQuery extends ModelCriteria
return $this->addUsingAlias(ProductSaleElementsTableMap::WEIGHT, $weight, $comparison);
}
/**
* Filter the query on the is_default column
*
* Example usage:
* <code>
* $query->filterByIsDefault(true); // WHERE is_default = true
* $query->filterByIsDefault('yes'); // WHERE is_default = true
* </code>
*
* @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 ChildProductSaleElementsQuery 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(ProductSaleElementsTableMap::IS_DEFAULT, $isDefault, $comparison);
}
/**
* Filter the query on the created_at column
*

View File

@@ -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));
}
}

View File

@@ -3,8 +3,30 @@
namespace Thelia\Model;
use Thelia\Model\Base\FeatureTemplate as BaseFeatureTemplate;
use Propel\Runtime\Connection\ConnectionInterface;
class FeatureTemplate extends BaseFeatureTemplate
class FeatureTemplate extends BaseFeatureTemplate
{
use \Thelia\Model\Tools\ModelEventDispatcherTrait;
use \Thelia\Model\Tools\PositionManagementTrait;
/**
* Calculate next position relative to our template
*/
protected function addCriteriaToPositionQuery($query)
{
$query->filterByTemplateId($this->getTemplateId());
}
/**
* {@inheritDoc}
*/
public function preInsert(ConnectionInterface $con = null)
{
// Set the current position for the new object
$this->setPosition($this->getNextPosition());
return true;
}
}

View File

@@ -57,7 +57,7 @@ class AttributeTemplateTableMap extends TableMap
/**
* The total number of columns
*/
const NUM_COLUMNS = 5;
const NUM_COLUMNS = 7;
/**
* The number of lazy-loaded columns
@@ -67,7 +67,7 @@ class AttributeTemplateTableMap extends TableMap
/**
* The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS)
*/
const NUM_HYDRATE_COLUMNS = 5;
const NUM_HYDRATE_COLUMNS = 7;
/**
* the column name for the ID field
@@ -84,6 +84,16 @@ class AttributeTemplateTableMap extends TableMap
*/
const TEMPLATE_ID = 'attribute_template.TEMPLATE_ID';
/**
* the column name for the POSITION field
*/
const POSITION = 'attribute_template.POSITION';
/**
* the column name for the ATTRIBUTE_TEMPLATECOL field
*/
const ATTRIBUTE_TEMPLATECOL = 'attribute_template.ATTRIBUTE_TEMPLATECOL';
/**
* the column name for the CREATED_AT field
*/
@@ -106,12 +116,12 @@ class AttributeTemplateTableMap extends TableMap
* e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id'
*/
protected static $fieldNames = array (
self::TYPE_PHPNAME => array('Id', 'AttributeId', 'TemplateId', 'CreatedAt', 'UpdatedAt', ),
self::TYPE_STUDLYPHPNAME => array('id', 'attributeId', 'templateId', 'createdAt', 'updatedAt', ),
self::TYPE_COLNAME => array(AttributeTemplateTableMap::ID, AttributeTemplateTableMap::ATTRIBUTE_ID, AttributeTemplateTableMap::TEMPLATE_ID, AttributeTemplateTableMap::CREATED_AT, AttributeTemplateTableMap::UPDATED_AT, ),
self::TYPE_RAW_COLNAME => array('ID', 'ATTRIBUTE_ID', 'TEMPLATE_ID', 'CREATED_AT', 'UPDATED_AT', ),
self::TYPE_FIELDNAME => array('id', 'attribute_id', 'template_id', 'created_at', 'updated_at', ),
self::TYPE_NUM => array(0, 1, 2, 3, 4, )
self::TYPE_PHPNAME => array('Id', 'AttributeId', 'TemplateId', 'Position', 'AttributeTemplatecol', 'CreatedAt', 'UpdatedAt', ),
self::TYPE_STUDLYPHPNAME => array('id', 'attributeId', 'templateId', 'position', 'attributeTemplatecol', 'createdAt', 'updatedAt', ),
self::TYPE_COLNAME => array(AttributeTemplateTableMap::ID, AttributeTemplateTableMap::ATTRIBUTE_ID, AttributeTemplateTableMap::TEMPLATE_ID, AttributeTemplateTableMap::POSITION, AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL, AttributeTemplateTableMap::CREATED_AT, AttributeTemplateTableMap::UPDATED_AT, ),
self::TYPE_RAW_COLNAME => array('ID', 'ATTRIBUTE_ID', 'TEMPLATE_ID', 'POSITION', 'ATTRIBUTE_TEMPLATECOL', 'CREATED_AT', 'UPDATED_AT', ),
self::TYPE_FIELDNAME => array('id', 'attribute_id', 'template_id', 'position', 'attribute_templatecol', 'created_at', 'updated_at', ),
self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, )
);
/**
@@ -121,12 +131,12 @@ class AttributeTemplateTableMap extends TableMap
* e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0
*/
protected static $fieldKeys = array (
self::TYPE_PHPNAME => array('Id' => 0, 'AttributeId' => 1, 'TemplateId' => 2, 'CreatedAt' => 3, 'UpdatedAt' => 4, ),
self::TYPE_STUDLYPHPNAME => array('id' => 0, 'attributeId' => 1, 'templateId' => 2, 'createdAt' => 3, 'updatedAt' => 4, ),
self::TYPE_COLNAME => array(AttributeTemplateTableMap::ID => 0, AttributeTemplateTableMap::ATTRIBUTE_ID => 1, AttributeTemplateTableMap::TEMPLATE_ID => 2, AttributeTemplateTableMap::CREATED_AT => 3, AttributeTemplateTableMap::UPDATED_AT => 4, ),
self::TYPE_RAW_COLNAME => array('ID' => 0, 'ATTRIBUTE_ID' => 1, 'TEMPLATE_ID' => 2, 'CREATED_AT' => 3, 'UPDATED_AT' => 4, ),
self::TYPE_FIELDNAME => array('id' => 0, 'attribute_id' => 1, 'template_id' => 2, 'created_at' => 3, 'updated_at' => 4, ),
self::TYPE_NUM => array(0, 1, 2, 3, 4, )
self::TYPE_PHPNAME => array('Id' => 0, 'AttributeId' => 1, 'TemplateId' => 2, 'Position' => 3, 'AttributeTemplatecol' => 4, 'CreatedAt' => 5, 'UpdatedAt' => 6, ),
self::TYPE_STUDLYPHPNAME => array('id' => 0, 'attributeId' => 1, 'templateId' => 2, 'position' => 3, 'attributeTemplatecol' => 4, 'createdAt' => 5, 'updatedAt' => 6, ),
self::TYPE_COLNAME => array(AttributeTemplateTableMap::ID => 0, AttributeTemplateTableMap::ATTRIBUTE_ID => 1, AttributeTemplateTableMap::TEMPLATE_ID => 2, AttributeTemplateTableMap::POSITION => 3, AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL => 4, AttributeTemplateTableMap::CREATED_AT => 5, AttributeTemplateTableMap::UPDATED_AT => 6, ),
self::TYPE_RAW_COLNAME => array('ID' => 0, 'ATTRIBUTE_ID' => 1, 'TEMPLATE_ID' => 2, 'POSITION' => 3, 'ATTRIBUTE_TEMPLATECOL' => 4, 'CREATED_AT' => 5, 'UPDATED_AT' => 6, ),
self::TYPE_FIELDNAME => array('id' => 0, 'attribute_id' => 1, 'template_id' => 2, 'position' => 3, 'attribute_templatecol' => 4, 'created_at' => 5, 'updated_at' => 6, ),
self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, )
);
/**
@@ -149,6 +159,8 @@ class AttributeTemplateTableMap extends TableMap
$this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null);
$this->addForeignKey('ATTRIBUTE_ID', 'AttributeId', 'INTEGER', 'attribute', 'ID', true, null, null);
$this->addForeignKey('TEMPLATE_ID', 'TemplateId', 'INTEGER', 'template', 'ID', true, null, null);
$this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null);
$this->addColumn('ATTRIBUTE_TEMPLATECOL', 'AttributeTemplatecol', 'VARCHAR', false, 45, null);
$this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null);
$this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null);
} // initialize()
@@ -316,12 +328,16 @@ class AttributeTemplateTableMap extends TableMap
$criteria->addSelectColumn(AttributeTemplateTableMap::ID);
$criteria->addSelectColumn(AttributeTemplateTableMap::ATTRIBUTE_ID);
$criteria->addSelectColumn(AttributeTemplateTableMap::TEMPLATE_ID);
$criteria->addSelectColumn(AttributeTemplateTableMap::POSITION);
$criteria->addSelectColumn(AttributeTemplateTableMap::ATTRIBUTE_TEMPLATECOL);
$criteria->addSelectColumn(AttributeTemplateTableMap::CREATED_AT);
$criteria->addSelectColumn(AttributeTemplateTableMap::UPDATED_AT);
} else {
$criteria->addSelectColumn($alias . '.ID');
$criteria->addSelectColumn($alias . '.ATTRIBUTE_ID');
$criteria->addSelectColumn($alias . '.TEMPLATE_ID');
$criteria->addSelectColumn($alias . '.POSITION');
$criteria->addSelectColumn($alias . '.ATTRIBUTE_TEMPLATECOL');
$criteria->addSelectColumn($alias . '.CREATED_AT');
$criteria->addSelectColumn($alias . '.UPDATED_AT');
}

View File

@@ -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');

View File

@@ -156,7 +156,7 @@ class FeatureTableMap extends TableMap
// columns
$this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null);
$this->addColumn('VISIBLE', 'Visible', 'INTEGER', false, null, 0);
$this->addColumn('POSITION', 'Position', 'INTEGER', true, 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);
} // initialize()

View File

@@ -57,7 +57,7 @@ class FeatureTemplateTableMap 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 FeatureTemplateTableMap 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 ID field
@@ -84,6 +84,11 @@ class FeatureTemplateTableMap extends TableMap
*/
const TEMPLATE_ID = 'feature_template.TEMPLATE_ID';
/**
* the column name for the POSITION field
*/
const POSITION = 'feature_template.POSITION';
/**
* the column name for the CREATED_AT field
*/
@@ -106,12 +111,12 @@ class FeatureTemplateTableMap extends TableMap
* e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id'
*/
protected static $fieldNames = array (
self::TYPE_PHPNAME => array('Id', 'FeatureId', 'TemplateId', 'CreatedAt', 'UpdatedAt', ),
self::TYPE_STUDLYPHPNAME => array('id', 'featureId', 'templateId', 'createdAt', 'updatedAt', ),
self::TYPE_COLNAME => array(FeatureTemplateTableMap::ID, FeatureTemplateTableMap::FEATURE_ID, FeatureTemplateTableMap::TEMPLATE_ID, FeatureTemplateTableMap::CREATED_AT, FeatureTemplateTableMap::UPDATED_AT, ),
self::TYPE_RAW_COLNAME => array('ID', 'FEATURE_ID', 'TEMPLATE_ID', 'CREATED_AT', 'UPDATED_AT', ),
self::TYPE_FIELDNAME => array('id', 'feature_id', 'template_id', 'created_at', 'updated_at', ),
self::TYPE_NUM => array(0, 1, 2, 3, 4, )
self::TYPE_PHPNAME => array('Id', 'FeatureId', 'TemplateId', 'Position', 'CreatedAt', 'UpdatedAt', ),
self::TYPE_STUDLYPHPNAME => array('id', 'featureId', 'templateId', 'position', 'createdAt', 'updatedAt', ),
self::TYPE_COLNAME => array(FeatureTemplateTableMap::ID, FeatureTemplateTableMap::FEATURE_ID, FeatureTemplateTableMap::TEMPLATE_ID, FeatureTemplateTableMap::POSITION, FeatureTemplateTableMap::CREATED_AT, FeatureTemplateTableMap::UPDATED_AT, ),
self::TYPE_RAW_COLNAME => array('ID', 'FEATURE_ID', 'TEMPLATE_ID', 'POSITION', 'CREATED_AT', 'UPDATED_AT', ),
self::TYPE_FIELDNAME => array('id', 'feature_id', 'template_id', 'position', 'created_at', 'updated_at', ),
self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, )
);
/**
@@ -121,12 +126,12 @@ class FeatureTemplateTableMap extends TableMap
* e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0
*/
protected static $fieldKeys = array (
self::TYPE_PHPNAME => array('Id' => 0, 'FeatureId' => 1, 'TemplateId' => 2, 'CreatedAt' => 3, 'UpdatedAt' => 4, ),
self::TYPE_STUDLYPHPNAME => array('id' => 0, 'featureId' => 1, 'templateId' => 2, 'createdAt' => 3, 'updatedAt' => 4, ),
self::TYPE_COLNAME => array(FeatureTemplateTableMap::ID => 0, FeatureTemplateTableMap::FEATURE_ID => 1, FeatureTemplateTableMap::TEMPLATE_ID => 2, FeatureTemplateTableMap::CREATED_AT => 3, FeatureTemplateTableMap::UPDATED_AT => 4, ),
self::TYPE_RAW_COLNAME => array('ID' => 0, 'FEATURE_ID' => 1, 'TEMPLATE_ID' => 2, 'CREATED_AT' => 3, 'UPDATED_AT' => 4, ),
self::TYPE_FIELDNAME => array('id' => 0, 'feature_id' => 1, 'template_id' => 2, 'created_at' => 3, 'updated_at' => 4, ),
self::TYPE_NUM => array(0, 1, 2, 3, 4, )
self::TYPE_PHPNAME => array('Id' => 0, 'FeatureId' => 1, 'TemplateId' => 2, 'Position' => 3, 'CreatedAt' => 4, 'UpdatedAt' => 5, ),
self::TYPE_STUDLYPHPNAME => array('id' => 0, 'featureId' => 1, 'templateId' => 2, 'position' => 3, 'createdAt' => 4, 'updatedAt' => 5, ),
self::TYPE_COLNAME => array(FeatureTemplateTableMap::ID => 0, FeatureTemplateTableMap::FEATURE_ID => 1, FeatureTemplateTableMap::TEMPLATE_ID => 2, FeatureTemplateTableMap::POSITION => 3, FeatureTemplateTableMap::CREATED_AT => 4, FeatureTemplateTableMap::UPDATED_AT => 5, ),
self::TYPE_RAW_COLNAME => array('ID' => 0, 'FEATURE_ID' => 1, 'TEMPLATE_ID' => 2, 'POSITION' => 3, 'CREATED_AT' => 4, 'UPDATED_AT' => 5, ),
self::TYPE_FIELDNAME => array('id' => 0, 'feature_id' => 1, 'template_id' => 2, 'position' => 3, 'created_at' => 4, 'updated_at' => 5, ),
self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, )
);
/**
@@ -149,6 +154,7 @@ class FeatureTemplateTableMap extends TableMap
$this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null);
$this->addForeignKey('FEATURE_ID', 'FeatureId', 'INTEGER', 'feature', 'ID', true, null, null);
$this->addForeignKey('TEMPLATE_ID', 'TemplateId', 'INTEGER', 'template', 'ID', true, null, null);
$this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null);
$this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null);
$this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null);
} // initialize()
@@ -316,12 +322,14 @@ class FeatureTemplateTableMap extends TableMap
$criteria->addSelectColumn(FeatureTemplateTableMap::ID);
$criteria->addSelectColumn(FeatureTemplateTableMap::FEATURE_ID);
$criteria->addSelectColumn(FeatureTemplateTableMap::TEMPLATE_ID);
$criteria->addSelectColumn(FeatureTemplateTableMap::POSITION);
$criteria->addSelectColumn(FeatureTemplateTableMap::CREATED_AT);
$criteria->addSelectColumn(FeatureTemplateTableMap::UPDATED_AT);
} else {
$criteria->addSelectColumn($alias . '.ID');
$criteria->addSelectColumn($alias . '.FEATURE_ID');
$criteria->addSelectColumn($alias . '.TEMPLATE_ID');
$criteria->addSelectColumn($alias . '.POSITION');
$criteria->addSelectColumn($alias . '.CREATED_AT');
$criteria->addSelectColumn($alias . '.UPDATED_AT');
}

View File

@@ -57,7 +57,7 @@ class ProductSaleElementsTableMap extends TableMap
/**
* The total number of columns
*/
const NUM_COLUMNS = 9;
const NUM_COLUMNS = 10;
/**
* The number of lazy-loaded columns
@@ -67,7 +67,7 @@ class ProductSaleElementsTableMap extends TableMap
/**
* The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS)
*/
const NUM_HYDRATE_COLUMNS = 9;
const NUM_HYDRATE_COLUMNS = 10;
/**
* the column name for the ID field
@@ -104,6 +104,11 @@ class ProductSaleElementsTableMap extends TableMap
*/
const WEIGHT = 'product_sale_elements.WEIGHT';
/**
* the column name for the IS_DEFAULT field
*/
const IS_DEFAULT = 'product_sale_elements.IS_DEFAULT';
/**
* the column name for the CREATED_AT field
*/
@@ -126,12 +131,12 @@ class ProductSaleElementsTableMap extends TableMap
* e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id'
*/
protected static $fieldNames = array (
self::TYPE_PHPNAME => array('Id', 'ProductId', 'Ref', 'Quantity', 'Promo', 'Newness', 'Weight', 'CreatedAt', 'UpdatedAt', ),
self::TYPE_STUDLYPHPNAME => array('id', 'productId', 'ref', 'quantity', 'promo', 'newness', 'weight', 'createdAt', 'updatedAt', ),
self::TYPE_COLNAME => array(ProductSaleElementsTableMap::ID, ProductSaleElementsTableMap::PRODUCT_ID, ProductSaleElementsTableMap::REF, ProductSaleElementsTableMap::QUANTITY, ProductSaleElementsTableMap::PROMO, ProductSaleElementsTableMap::NEWNESS, ProductSaleElementsTableMap::WEIGHT, ProductSaleElementsTableMap::CREATED_AT, ProductSaleElementsTableMap::UPDATED_AT, ),
self::TYPE_RAW_COLNAME => array('ID', 'PRODUCT_ID', 'REF', 'QUANTITY', 'PROMO', 'NEWNESS', 'WEIGHT', 'CREATED_AT', 'UPDATED_AT', ),
self::TYPE_FIELDNAME => array('id', 'product_id', 'ref', 'quantity', 'promo', 'newness', 'weight', 'created_at', 'updated_at', ),
self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, )
self::TYPE_PHPNAME => array('Id', 'ProductId', 'Ref', 'Quantity', 'Promo', 'Newness', 'Weight', 'IsDefault', 'CreatedAt', 'UpdatedAt', ),
self::TYPE_STUDLYPHPNAME => array('id', 'productId', 'ref', 'quantity', 'promo', 'newness', 'weight', 'isDefault', 'createdAt', 'updatedAt', ),
self::TYPE_COLNAME => array(ProductSaleElementsTableMap::ID, ProductSaleElementsTableMap::PRODUCT_ID, ProductSaleElementsTableMap::REF, ProductSaleElementsTableMap::QUANTITY, ProductSaleElementsTableMap::PROMO, ProductSaleElementsTableMap::NEWNESS, ProductSaleElementsTableMap::WEIGHT, ProductSaleElementsTableMap::IS_DEFAULT, ProductSaleElementsTableMap::CREATED_AT, ProductSaleElementsTableMap::UPDATED_AT, ),
self::TYPE_RAW_COLNAME => array('ID', 'PRODUCT_ID', 'REF', 'QUANTITY', 'PROMO', 'NEWNESS', 'WEIGHT', 'IS_DEFAULT', 'CREATED_AT', 'UPDATED_AT', ),
self::TYPE_FIELDNAME => array('id', 'product_id', 'ref', 'quantity', 'promo', 'newness', 'weight', 'is_default', 'created_at', 'updated_at', ),
self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, )
);
/**
@@ -141,12 +146,12 @@ class ProductSaleElementsTableMap extends TableMap
* e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0
*/
protected static $fieldKeys = array (
self::TYPE_PHPNAME => array('Id' => 0, 'ProductId' => 1, 'Ref' => 2, 'Quantity' => 3, 'Promo' => 4, 'Newness' => 5, 'Weight' => 6, 'CreatedAt' => 7, 'UpdatedAt' => 8, ),
self::TYPE_STUDLYPHPNAME => array('id' => 0, 'productId' => 1, 'ref' => 2, 'quantity' => 3, 'promo' => 4, 'newness' => 5, 'weight' => 6, 'createdAt' => 7, 'updatedAt' => 8, ),
self::TYPE_COLNAME => array(ProductSaleElementsTableMap::ID => 0, ProductSaleElementsTableMap::PRODUCT_ID => 1, ProductSaleElementsTableMap::REF => 2, ProductSaleElementsTableMap::QUANTITY => 3, ProductSaleElementsTableMap::PROMO => 4, ProductSaleElementsTableMap::NEWNESS => 5, ProductSaleElementsTableMap::WEIGHT => 6, ProductSaleElementsTableMap::CREATED_AT => 7, ProductSaleElementsTableMap::UPDATED_AT => 8, ),
self::TYPE_RAW_COLNAME => array('ID' => 0, 'PRODUCT_ID' => 1, 'REF' => 2, 'QUANTITY' => 3, 'PROMO' => 4, 'NEWNESS' => 5, 'WEIGHT' => 6, 'CREATED_AT' => 7, 'UPDATED_AT' => 8, ),
self::TYPE_FIELDNAME => array('id' => 0, 'product_id' => 1, 'ref' => 2, 'quantity' => 3, 'promo' => 4, 'newness' => 5, 'weight' => 6, 'created_at' => 7, 'updated_at' => 8, ),
self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, )
self::TYPE_PHPNAME => array('Id' => 0, 'ProductId' => 1, 'Ref' => 2, 'Quantity' => 3, 'Promo' => 4, 'Newness' => 5, 'Weight' => 6, 'IsDefault' => 7, 'CreatedAt' => 8, 'UpdatedAt' => 9, ),
self::TYPE_STUDLYPHPNAME => array('id' => 0, 'productId' => 1, 'ref' => 2, 'quantity' => 3, 'promo' => 4, 'newness' => 5, 'weight' => 6, 'isDefault' => 7, 'createdAt' => 8, 'updatedAt' => 9, ),
self::TYPE_COLNAME => array(ProductSaleElementsTableMap::ID => 0, ProductSaleElementsTableMap::PRODUCT_ID => 1, ProductSaleElementsTableMap::REF => 2, ProductSaleElementsTableMap::QUANTITY => 3, ProductSaleElementsTableMap::PROMO => 4, ProductSaleElementsTableMap::NEWNESS => 5, ProductSaleElementsTableMap::WEIGHT => 6, ProductSaleElementsTableMap::IS_DEFAULT => 7, ProductSaleElementsTableMap::CREATED_AT => 8, ProductSaleElementsTableMap::UPDATED_AT => 9, ),
self::TYPE_RAW_COLNAME => array('ID' => 0, 'PRODUCT_ID' => 1, 'REF' => 2, 'QUANTITY' => 3, 'PROMO' => 4, 'NEWNESS' => 5, 'WEIGHT' => 6, 'IS_DEFAULT' => 7, 'CREATED_AT' => 8, 'UPDATED_AT' => 9, ),
self::TYPE_FIELDNAME => array('id' => 0, 'product_id' => 1, 'ref' => 2, 'quantity' => 3, 'promo' => 4, 'newness' => 5, 'weight' => 6, 'is_default' => 7, 'created_at' => 8, 'updated_at' => 9, ),
self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, )
);
/**
@@ -167,11 +172,12 @@ 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);
$this->addColumn('WEIGHT', 'Weight', 'FLOAT', false, null, null);
$this->addColumn('WEIGHT', 'Weight', 'FLOAT', false, null, 0);
$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()
@@ -355,6 +361,7 @@ class ProductSaleElementsTableMap extends TableMap
$criteria->addSelectColumn(ProductSaleElementsTableMap::PROMO);
$criteria->addSelectColumn(ProductSaleElementsTableMap::NEWNESS);
$criteria->addSelectColumn(ProductSaleElementsTableMap::WEIGHT);
$criteria->addSelectColumn(ProductSaleElementsTableMap::IS_DEFAULT);
$criteria->addSelectColumn(ProductSaleElementsTableMap::CREATED_AT);
$criteria->addSelectColumn(ProductSaleElementsTableMap::UPDATED_AT);
} else {
@@ -365,6 +372,7 @@ class ProductSaleElementsTableMap extends TableMap
$criteria->addSelectColumn($alias . '.PROMO');
$criteria->addSelectColumn($alias . '.NEWNESS');
$criteria->addSelectColumn($alias . '.WEIGHT');
$criteria->addSelectColumn($alias . '.IS_DEFAULT');
$criteria->addSelectColumn($alias . '.CREATED_AT');
$criteria->addSelectColumn($alias . '.UPDATED_AT');
}

View File

@@ -87,12 +87,48 @@ class Product extends BaseProduct
return $this;
}
public function updateDefaultCategory($defaultCategoryId) {
// Allow uncategorized products (NULL instead of 0, to bypass delete cascade constraint)
if ($defaultCategoryId <= 0) $defaultCategoryId = NULL;
// Update the default category
$productCategory = ProductCategoryQuery::create()
->filterByProductId($this->getId())
->filterByDefaultCategory(true)
->findOne()
;
echo "newcat= $defaultCategoryId ";
var_dump($productCategory);
if ($productCategory == null || $productCategory->getCategoryId() != $defaultCategoryId) {
exit;
// Delete the old default category
if ($productCategory !== null) $productCategory->delete();
// Add the new default category
$productCategory = new ProductCategory();
$productCategory
->setProduct($this)
->setCategoryId($defaultCategoryId)
->setDefaultCategory(true)
->save()
;
}
}
/**
* 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);
@@ -105,18 +141,13 @@ class Product extends BaseProduct
$this->save($con);
// Add the default category
$pc = new ProductCategory();
$pc
->setProduct($this)
->setCategoryId($defaultCategoryId)
->setDefaultCategory(true)
->save($con)
;
$this->updateDefaultCategory($defaultCategoryId);
// Set the position
$this->setPosition($this->getNextPosition())->save($con);
$this->setTaxRuleId($taxRuleId);
// Create an empty product sale element
$sale_elements = new ProductSaleElements();
@@ -125,7 +156,8 @@ class Product extends BaseProduct
->setRef($this->getRef())
->setPromo(0)
->setNewness(0)
->setWeight(0)
->setWeight($baseWeight)
->setIsDefault(true)
->save($con)
;
@@ -134,9 +166,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)
;

View File

@@ -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;

View File

@@ -126,7 +126,8 @@ trait PositionManagementTrait {
$result->setDispatcher($this->getDispatcher())->setPosition($my_position)->save();
$cnx->commit();
} catch (Exception $e) {
}
catch (Exception $e) {
$cnx->rollback();
}
}
@@ -179,7 +180,10 @@ trait PositionManagementTrait {
try {
foreach ($results as $result) {
$result->setDispatcher($this->getDispatcher())->setPosition($result->getPosition() + $delta)->save($cnx);
$objNewPosition = $result->getPosition() + $delta;
$result->setDispatcher($this->getDispatcher())->setPosition($objNewPosition)->save($cnx);
}
$this
@@ -188,7 +192,8 @@ trait PositionManagementTrait {
;
$cnx->commit();
} catch (Exception $e) {
}
catch (Exception $e) {
$cnx->rollback();
}
}

View File

@@ -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();
@@ -442,7 +443,7 @@ try {
$featureAvId[array_rand($featureAvId, 1)]
);
} else { //no av
$featureProduct->setByDefault($faker->text(10));
$featureProduct->setFreeTextValue($faker->text(10));
}
$featureProduct->save();

View File

@@ -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_US', '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_US', '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

View File

@@ -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;
@@ -186,7 +186,7 @@ CREATE TABLE `feature`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`visible` INTEGER DEFAULT 0,
`position` INTEGER NOT NULL,
`position` INTEGER,
`created_at` DATETIME,
`updated_at` DATETIME,
PRIMARY KEY (`id`)
@@ -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,
@@ -262,6 +262,7 @@ CREATE TABLE `feature_template`
`id` INTEGER NOT NULL AUTO_INCREMENT,
`feature_id` INTEGER NOT NULL,
`template_id` INTEGER NOT NULL,
`position` INTEGER,
`created_at` DATETIME,
`updated_at` DATETIME,
PRIMARY KEY (`id`),
@@ -358,11 +359,12 @@ 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,
`weight` FLOAT,
`weight` FLOAT DEFAULT 0,
`is_default` TINYINT(1) DEFAULT 0,
`created_at` DATETIME,
`updated_at` DATETIME,
PRIMARY KEY (`id`),
@@ -386,6 +388,8 @@ CREATE TABLE `attribute_template`
`id` INTEGER NOT NULL AUTO_INCREMENT,
`attribute_id` INTEGER NOT NULL,
`template_id` INTEGER NOT NULL,
`position` INTEGER,
`attribute_templatecol` VARCHAR(45),
`created_at` DATETIME,
`updated_at` DATETIME,
PRIMARY KEY (`id`),

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,248 @@
{loop name="product_edit" type="product" visible="*" id=$product_id backend_context="1" lang=$edit_language_id}
<div class="form-container">
<div class="row">
<div class="col-md-12">
<p></p> {* <---- FIXME Lame ! *}
<form method="POST" class="clearfix" action="{url path="/admin/product/$ID/set-product-template"}" id="product_template_form">
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="current_tab" value="attributes" />
<div class="row">
<div class="col-md-12">
<div class="well well-sm">
<p>{intl
l="To use features or attributes on this product, please select a product template. You can define product templates in the <a href=\"%tpl_mgmt_url\" target=\"tpl_window\">configuration section</a> of the administration."
tpl_mgmt_url={url path='/admin/configuration/templates'}
}
</p>
<label for="template_id" class="control-label">
{intl l='Current product template'} :
</label>
<div class="input-group">
<select required="required" name="template_id" id="template_id" class="form-control">
<option value="0">{intl l='Do not use a product template'}</option>
{loop name="product_template_select" type="template"}
<option value="{$ID}" {if $TEMPLATE == $ID}selected="selected"{/if}>{$NAME}</option>
{/loop}
</select>
<span class="input-group-btn" id="apply_template_button">
<button class="btn btn-default btn-primary action-btn" type="submit">{intl l="Apply"}</button>
</span>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
{* Check if a product template is defined *}
<div class="row">
<div class="col-md-12">
<form method="POST" action="{url path="/admin/product/$ID/update-attributes-and-features"}" id="attribute_form">
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="current_tab" value="attributes" />
{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}"
}
{* -- Begin attributes management ------------------------------- *}
<div class="row">
<div class="col-md-12">
<div class="well well-sm">
<div class="form-group">
<p class="title title-without-tabs">{intl l='Product Attributes'}</p>
<p>
{if $TEMPLATE}
{intl
l="You can change template attributes and their positions in <a href=\"%tpl_mgmt_url\" target=\"tpl_window\">the template configuration page</a>."
tpl_mgmt_url={url path='/admin/configuration/templates/update' template_id=$TEMPLATE}
}
{else}
{intl
l="You can change attributes and their positions in <a href=\"%tpl_mgmt_url\" target=\"tpl_window\">the attributes configuration page</a>."
tpl_mgmt_url={url path='/admin/configuration/attributes'}
}
{/if}
</p>
<div class="table-responsive">
<table class="table table-striped table-condensed table-left-aligned">
<thead>
<tr>
<th>{intl l='ID'}</th>
<th>{intl l='Attribute Name'}</th>
{module_include location='product_attributes_table_header'}
</tr>
</thead>
<tbody>
{loop name="product-attributes" type="attribute" order="manual" product=$product_id backend_context="1" lang="$edit_language_id"}
<tr>
<td>{$ID}</td>
<td>{$TITLE}</td>
{module_include location='product_features_table_row'}
</tr>
{/loop}
{elseloop rel="product-attributes"}
<tr>
<td colspan="2">
<div class="alert alert-info">
{intl l="This product template does not contains any features"}
</div>
</td>
</tr>
{/elseloop}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{* -- Begin features management ---------------------------------- *}
<div class="row">
<div class="col-md-12">
<div class="well well-sm">
<div class="form-group">
<p class="title title-without-tabs">{intl l='Product Features'}</p>
<p>
{if $TEMPLATE}
{intl
l="You can change templates features and their positions in <a href=\"%tpl_mgmt_url\" target=\"tpl_window\">the template configuration page</a>."
tpl_mgmt_url={url path='/admin/configuration/templates/update' template_id=$TEMPLATE}
}
{else}
{intl
l="You can change feature and their positions in <a href=\"%tpl_mgmt_url\" target=\"tpl_window\">the features configuration page</a>."
tpl_mgmt_url={url path='/admin/configuration/features'}
}
{/if}
</p>
<div class="table-responsive">
<table class="table table-striped table-condensed table-left-aligned">
<thead>
<tr>
<th>{intl l='ID'}</th>
<th>{intl l='Feature Name'}</th>
<th>{intl l='Feature value for this product'}</th>
{module_include location='product_features_table_header'}
</tr>
</thead>
<tbody>
{loop name="product-features" type="feature" order="manual" product=$product_id backend_context="1" lang="$edit_language_id"}
<tr>
<td>{$ID}</td>
<td>{$TITLE}</td>
<td>
{* Multiple values *}
{ifloop rel="product-features-av"}
{* load all selected values in an array to speed up things a little *}
{$selected = array()}
{loop name="free-text-value" exclude_free_text="true" type="feature_value" product=$product_id feature=$ID backend_context="1" lang="$edit_language_id"}
{$selected[] = $FEATURE_AV_ID}
{/loop}
{capture "select_options"}
{loop name="product-features-av" type="feature-availability" feature=$ID order="manual" backend_context="1" lang="$edit_language_id"}
<option value="{$ID}" {if in_array($ID, $selected)}selected="selected"{/if}>{$TITLE}</option>
{$options_count = $LOOP_COUNT} {* LOOP_COUNT is only available inside the loop ! *}
{/loop}
{/capture}
<div class="input-form">
<select multiple="multiple" name="feature_value[{$ID}][]" id="feature_value_{$ID}" size="{$options_count}" class="form-control">
{$smarty.capture.select_options nofilter}
</select>
</div>
<span class="help-block text-right">
{intl l='Use Ctrl+click to select more than one value. You can also <a href="#" class="clear_feature_value" data-id="%id">clear selected values</a>.' id=$ID}
</span>
{/ifloop}
{* Free text *}
{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}
<input type="text" id="feature_text_value_{$ID}" name="feature_text_value[{$ID}]" title="{intl l='Enter here the feature value as free text'}" placeholder="{intl l='Feature value'}" class="form-control" value="{$feature_value|default:''}">
{/elseloop}
</td>
{module_include location='product_features_table_row'}
</tr>
{/loop}
{elseloop rel="product-features"}
<tr>
<td colspan="3">
<div class="alert alert-info">
{intl l="This product template does not contains any features"}
</div>
</td>
</tr>
{/elseloop}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
{/loop}
<script>
$(function() {
// Unselect all options in attribute + feature tab
$('.clear_feature_value').click(function(event){
$('#feature_value_' + $(this).data('id') + ' option').prop('selected', false);
event.preventDefault();
});
});
</script>

View File

@@ -0,0 +1,576 @@
{loop name="product_edit" type="product" visible="*" id=$product_id backend_context="1" lang=$edit_language_id}
<div class="form-container">
{include
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}"
}
<div class="row">
{* -- Begin related content management ------------------------------ *}
<div class="col-md-6">
<div class="well well-sm">
<div class="form-group">
<form method="POST" action="{url path='/admin/products/content/add'}" id="related_content_form">
<p class="title title-without-tabs">{intl l='Related content'}</p>
<p>{intl l='You can attach here some content to this product'}</p>
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="current_tab" value="related" />
{ifloop rel="folders"}
<div class="form-group">
<select name="folder_id" id="folder_id" class="form-control">
<option value="">{intl l='Select a folder...'}</option>
{loop name="folders" type="folder-tree" folder="0" backend_context="1" lang="$edit_language_id"}
<option value="{$ID}" style="padding-left: {3 + $LEVEL * 20}px">{$TITLE}</option>
{/loop}
</select>
<span class="help-block">{intl l='Select a folder to get its content'}</span>
</div>
<div id="content_selector" class="hide">
<div class="input-group">
<select required="required" name="content_id" id="content_id" class="form-control">
<option value="">{intl l='Select a folder content...'}</option>
</select>
<span class="input-group-btn" id="content_add_button">
<button class="btn btn-default btn-primary action-btn" type="submit"><span class="glyphicon glyphicon-plus-sign"></span></button>
</span>
</div>
<span class="help-block">{intl l='Select a content and click (+) to add it to this product'}</span>
</div>
<div id="content_selector_empty" class="hide">
<div class="alert alert-info">
{intl l="No available content in this folder"}
</div>
</div>
{/ifloop}
{elseloop rel="folders"}
<div class="alert alert-info">{intl l="No folders found"}</div>
{/elseloop}
</form>
</div>
<div class="table-responsive">
<table class="table table-striped table-condensed table-left-aligned">
<thead>
<tr>
<th>{intl l='ID'}</th>
<th>{intl l='Content title'}</th>
<th class="text-center">{intl l='Position'}</th>
{module_include location='product_contents_table_header'}
<th class="actions">{intl l="Actions"}</th>
</tr>
</thead>
<tbody>
{loop name="assigned_contents" type="associated_content" product="$product_id" backend_context="1" lang="$edit_language_id"}
<tr>
<td>{$ID}</td>
<td>
{$TITLE}
</td>
<td class="text-center">
{admin_position_block
permission="admin.products.edit"
path={url path='/admin/product/update-content-position' product_id=$product_id current_tab="related"}
url_parameter="content_id"
in_place_edit_class="contentPositionChange"
position=$POSITION
id=$ID
}
</td>
{module_include location='product_contents_table_row'}
<td class="actions">
<div class="btn-group">
{loop type="auth" name="can_create" roles="ADMIN" permissions="admin.product.content.delete"}
<a class="btn btn-default btn-xs delete-content" title="{intl l='Delete this content'}" href="#delete_content_dialog" data-id="{$ID}" data-toggle="modal">
<span class="glyphicon glyphicon-trash"></span>
</a>
{/loop}
</div>
</td>
</tr>
{/loop}
{elseloop rel="assigned_contents"}
<tr>
<td colspan="4">
<div class="alert alert-info">
{intl l="This product contains no contents"}
</div>
</td>
</tr>
{/elseloop}
</tbody>
</table>
</div>
</div>
</div>
{* -- End related content management -------------------------------- *}
{* -- Begin accessories management ---------------------------------- *}
<div class="col-md-6">
<div class=" well well-sm">
<div class="form-group">
<form method="POST" action="{url path='/admin/products/accessory/add'}" id="accessory_form">
<p class="title title-without-tabs">{intl l='Product accessories'}</p>
<p>{intl l='Define here this product\'s accessories'}</p>
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="current_tab" value="related" />
{ifloop rel="categories"}
<div class="form-group">
<select name="accessory_category_id" id="accessory_category_id" class="form-control">
<option value="">{intl l='Select a category...'}</option>
{loop name="categories" type="category-tree" category="0" backend_context="1" lang="$edit_language_id"}
<option value="{$ID}" style="padding-left: {3 + $LEVEL * 20}px">{$TITLE}</option>
{/loop}
</select>
<span class="help-block">{intl l='Select a category to get its products'}</span>
</div>
<div id="accessory_selector" class="hide">
<div class="input-group">
<select required="required" name="accessory_id" id="accessory_id" class="form-control">
<option value="">{intl l='Select a product...'}</option>
</select>
<span class="input-group-btn" id="accessory_add_button">
<button class="btn btn-default btn-primary action-btn" type="submit"><span class="glyphicon glyphicon-plus-sign"></span></button>
</span>
</div>
<span class="help-block">{intl l='Select a product and click (+) to add it as an accessory'}</span>
</div>
<div id="accessory_selector_empty" class="hide">
<div class="alert alert-info">
{intl l="No available product in this category"}
</div>
</div>
{/ifloop}
{elseloop rel="categories"}
<div class="alert alert-info">{intl l="No categories found"}</div>
{/elseloop}
</form>
</div>
<div class="table-responsive">
<table class="table table-striped table-condensed table-left-aligned">
<thead>
<tr>
<th>{intl l='ID'}</th>
<th>{intl l='Accessory title'}</th>
<th class="text-center">{intl l='Position'}</th>
{module_include location='product_accessories_table_header'}
<th class="actions">{intl l="Actions"}</th>
</tr>
</thead>
<tbody>
{loop name="assigned_accessories" order="accessory" type="accessory" product="$product_id" backend_context="1" lang="$edit_language_id"}
<tr>
<td>{$ID}</td>
<td>
{$TITLE}
</td>
<td class="text-center">
{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
}
</td>
{module_include location='product_accessories_table_row'}
<td class="actions">
<div class="btn-group">
{loop type="auth" name="can_create" roles="ADMIN" permissions="admin.product.accessory.delete"}
<a class="btn btn-default btn-xs delete-accessory" title="{intl l='Delete this accessory'}" href="#delete_accessory_dialog" data-id="{$ID}" data-toggle="modal">
<span class="glyphicon glyphicon-trash"></span>
</a>
{/loop}
</div>
</td>
</tr>
{/loop}
{elseloop rel="assigned_accessories"}
<tr>
<td colspan="4">
<div class="alert alert-info">
{intl l="This product contains no accessories"}
</div>
</td>
</tr>
{/elseloop}
</tbody>
</table>
</div>
</div>
</div>
{* -- End accessories management ------------------------------------ *}
</div>
<div class="row">
{* -- Begin categories management ----------------------------------- *}
<div class="col-md-6">
<div class="well well-sm">
<div class="form-group">
<form method="POST" action="{url path='/admin/products/category/add'}" id="related_content_form">
<p class="title title-without-tabs">{intl l='Additional categories'}</p>
<p>{intl l='A product could be attached to more than one category. Select here the additional categories for this product.'}
{loop name="default_category" type="category" id=$DEFAULT_CATEGORY}
{intl l='You can change the default category (%title) in the "General" tab.' title=$TITLE}
{/loop}
{$exclude_from_tree = "-1"}
{loop name="additional_categories" type="category" product=$product_id exclude=$DEFAULT_CATEGORY backend_context="1" lang="$edit_language_id"}
{$exclude_from_tree = "$exclude_from_tree,$ID"}
{/loop}
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="current_tab" value="related" />
{ifloop rel="categories"}
<div class="input-group">
<select name="additional_category_id" id="accessory_category_id" class="form-control">
<option value="">{intl l='Select a category...'}</option>
{loop name="categories" type="category-tree" category="0" exclude=$exclude_from_tree backend_context="1" lang="$edit_language_id"}
<option value="{$ID}" style="padding-left: {3 + $LEVEL * 20}px" {if $DEFAULT_CATEGORY==$ID}disabled="disabled"{/if}>
{$TITLE} {if $DEFAULT_CATEGORY==$ID}{intl l=' (default)'}{/if}
</option>
{/loop}
</select>
<span class="input-group-btn" id="content_add_button">
<button class="btn btn-default btn-primary action-btn" type="submit"><span class="glyphicon glyphicon-plus-sign"></span></button>
</span>
</div>
<span class="help-block">{intl l='Select a category and click (+) to add it to the additional category list'}</span>
{/ifloop}
{elseloop rel="categories"}
<div class="alert alert-info">{intl l="No categories found"}</div>
{/elseloop}
</form>
</div>
<div class="table-responsive">
<table class="table table-striped table-condensed table-left-aligned">
<thead>
<tr>
<th>{intl l='ID'}</th>
<th>{intl l='Category title'}</th>
{module_include location='product_categories_table_header'}
<th class="actions">{intl l="Actions"}</th>
</tr>
</thead>
<tbody>
{loop name="additional_categories" type="category" product=$product_id exclude=$DEFAULT_CATEGORY backend_context="1" lang="$edit_language_id"}
<tr>
<td>{$ID}</td>
<td>
{$TITLE}
</td>
{module_include location='product_categories_table_row'}
<td class="actions">
<div class="btn-group">
{loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.product.category.delete"}
<a class="btn btn-default btn-xs delete-category" title="{intl l='Remove the product from this category'}" href="#delete_category_dialog" data-id="{$ID}" data-toggle="modal">
<span class="glyphicon glyphicon-trash"></span>
</a>
{/loop}
</div>
</td>
</tr>
{/loop}
{elseloop rel="additional_categories"}
<tr>
<td colspan="3">
<div class="alert alert-info">
{intl l="This product doesn't belong to any additional category."}
</div>
</td>
</tr>
{/elseloop}
</tbody>
</table>
</div>
</div>
</div>
{* -- End categories management ------------------------------------- *}
</div>
</div>
{* Delete related content confirmation dialog *}
{capture "delete_content_dialog"}
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="content_id" id="content_delete_id" value="" />
<input type="hidden" name="folder_id" id="folder_delete_id" value="" />
<input type="hidden" name="current_tab" value="related" />
{/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/content/delete'}
form_content = {$smarty.capture.delete_content_dialog nofilter}
}
{* Delete accessory confirmation dialog *}
{capture "delete_accessory_dialog"}
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="accessory_id" id="accessory_delete_id" value="" />
<input type="hidden" name="accessory_category_id" id="accessory_category_delete_id" value="" />
<input type="hidden" name="current_tab" value="related" />
{/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}
}
{* Delete category confirmation dialog *}
{capture "delete_category_dialog"}
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="additional_category_id" id="additional_category_delete_id" value="" />
<input type="hidden" name="current_tab" value="related" />
{/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}
}
<script>
$(function() {
// Set proper content ID in delete content from
$('a.delete-content').click(function(ev) {
$('#content_delete_id').val($(this).data('id'));
$('#folder_delete_id').val($('#folder_id').val());
});
// Set proper content ID in accessory delete from
$('a.delete-accessory').click(function(ev) {
$('#accessory_delete_id').val($(this).data('id'));
$('#accessory_category_delete_id').val($('#accessory_category_id').val());
});
// Set proper content ID in accessory delete from
$('a.delete-category').click(function(ev) {
$('#additional_category_delete_id').val($(this).data('id'));
});
// Load content on folder selection
$('#folder_id').change(function(event) {
var val = $(this).val();
if (val != "") {
$.ajax({
url : '{url path="/admin/product/$product_id/available-content/"}' + $(this).val() + '.xml',
type : 'get',
dataType : 'json',
success : function(json) {
$('#content_id :not(:first-child)').remove();
var have_content = false;
$.each(json, function(idx, value) {
$('#content_id').append($('<option>').text(value.title).attr('value', value.id));
have_content = true; // Lame...
});
if (have_content) {
$('#content_selector_empty').addClass('hide');
$('#content_selector').removeClass('hide');
}
else {
$('#content_selector_empty').removeClass('hide');
$('#content_selector').addClass('hide');
}
}
});
}
else {
$('#content_selector_empty').addClass('hide');
$('#content_selector').addClass('hide');
}
});
// Load accessory on category selection
$('#accessory_category_id').change(function(event) {
var val = $(this).val();
if (val != "") {
$.ajax({
url : '{url path="/admin/product/$product_id/available-accessories/"}' + $(this).val() + '.xml',
type : 'get',
dataType : 'json',
success : function(json) {
$('#accessory_id :not(:first-child)').remove();
var have_content = false;
$.each(json, function(idx, value) {
$('#accessory_id').append($('<option>').text(value.title).attr('value', value.id));
have_content = true; // Lame...
});
if (have_content) {
$('#accessory_selector_empty').addClass('hide');
$('#accessory_selector').removeClass('hide');
}
else {
$('#accessory_selector_empty').removeClass('hide');
$('#accessory_selector').addClass('hide');
}
}
});
}
else {
$('#accessory_selector_empty').addClass('hide');
$('#accessory_selector').addClass('hide');
}
});
{* Inline editing of accessory position using bootstrap-editable *}
$('.accessoryPositionChange').editable({
type : 'text',
title : '{intl l="Enter new accessory position"}',
mode : 'popup',
inputclass : 'input-mini',
placement : 'left',
success : function(response, newValue) {
// The URL template
var url = "{url noamp='1' path='/admin/product/update-accessory-position' accessory_id='__ID__' position='__POS__' product_id=$product_id current_tab='related' }";
// Perform subtitutions
url = url.replace('__ID__', $(this).data('id')).replace('__POS__', newValue);
// Reload the page
location.href = url;
}
});
$('.contentPositionChange').editable({
type : 'text',
title : '{intl l="Enter new content position"}',
mode : 'popup',
inputclass : 'input-mini',
placement : 'left',
success : function(response, newValue) {
// The URL template
var url = "{url noamp='1' path='/admin/product/update-content-position' content_id='__ID__' position='__POS__' product_id=$product_id current_tab='related' }";
// Perform subtitutions
url = url.replace('__ID__', $(this).data('id')).replace('__POS__', newValue);
// Reload the page
location.href = url;
}
});
// Initialize folder (id={$folder_id}) select value
{if $folder_id != 0}
$('#folder_id').val("{$folder_id}").change();
{/if}
// Initialize accessory category id (id={$accessory_category_id}) select value
{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();
});
});
</script>
{/loop}

View File

@@ -1,12 +1,12 @@
<div class="form-group">
{ifloop rel="free_attributes"}
<form action="{url path='/admin/configuration/templates/attributes/add'}">
<form method="POST" action="{url path='/admin/configuration/templates/attributes/add'}">
<input type="hidden" name="template_id" value="{$template_id}" />
<div class="input-group">
<select required="required" name="attribute_id" id="attribute_id" class="form-control">
<option value="">Select an attribute...</option>
<option value="">{intl l='Select an attribute...'}</option>
{loop name="free_attributes" type="attribute" exclude_template="$template_id" backend_context="1" lang="$edit_language_id"}
<option value="{$ID}">{$TITLE}</option>
{/loop}
@@ -33,6 +33,8 @@
<th>{intl l='Attribute title'}</th>
<th class="text-center">{intl l='Position'}</th>
{module_include location='template_attributes_table_header'}
<th class="actions">{intl l="Actions"}</th>
@@ -44,8 +46,17 @@
<tr>
<td>{$ID}</td>
<td>
{$TITLE}
<td>{$TITLE}</td>
<td class="text-center">
{admin_position_block
permission="admin.templates.edit"
path={url path="admin/template/update-attribute-position" template_id=$template_id}
url_parameter="attribute_id"
in_place_edit_class="attributePositionChange"
position=$POSITION
id=$ID
}
</td>
{module_include location='template_attributes_table_row'}
@@ -64,7 +75,7 @@
{elseloop rel="assigned_attributes"}
<tr>
<td colspan="3">
<td colspan="4">
<div class="alert alert-info">
{intl l="This template contains no attributes"}
</div>
@@ -93,11 +104,33 @@
}
<script>
$(function() {
// Set proper attribute ID in delete attribute from
$('a.delete-attribute').click(function(ev) {
$('#attribute_delete_id').val($(this).data('id'));
});
{* Inline editing of object position using bootstrap-editable *}
$('.attributePositionChange').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-attribute-position" template_id=$template_id attribute_id='__ID__' position='__POS__'}";
// Perform subtitutions
url = url.replace('__ID__', $(this).data('id')).replace('__POS__', newValue);
// Reload the page
location.href = url;
}
});
});
</script>

View File

@@ -1,12 +1,12 @@
<div class="form-group">
{ifloop rel="free_features"}
<form action="{url path='/admin/configuration/templates/features/add'}">
<form method="POST" action="{url path='/admin/configuration/templates/features/add'}">
<input type="hidden" name="template_id" value="{$template_id}" />
<div class="input-group">
<select required="required" name="feature_id" id="feature_id" class="form-control">
<option value="">Select an feature...</option>
<option value="">{intl l='Select an feature...'}</option>
{loop name="free_features" type="feature" exclude_template="$template_id" backend_context="1" lang="$edit_language_id"}
<option value="{$ID}">{$TITLE}</option>
{/loop}
@@ -33,6 +33,8 @@
<th>{intl l='Feature title'}</th>
<th class="text-center">{intl l='Position'}</th>
{module_include location='template_features_table_header'}
<th class="actions">{intl l="Actions"}</th>
@@ -48,6 +50,17 @@
{$TITLE}
</td>
<td class="text-center">
{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
}
</td>
{module_include location='template_features_table_row'}
<td class="actions">
@@ -64,7 +77,7 @@
{elseloop rel="assigned_features"}
<tr>
<td colspan="3">
<td colspan="4">
<div class="alert alert-info">
{intl l="This template contains no features"}
</div>
@@ -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;
}
});
});
</script>

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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'))

View File

@@ -256,7 +256,7 @@
}
</th>
<th>&nbsp;</th>
<th class="actions">{intl l="Actions"}</th>
</tr>
</thead>
@@ -303,7 +303,7 @@
}
</td>
<td>
<td class="actions">
<div class="btn-group">
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.product.edit"}
<a class="btn btn-default btn-xs" title="{intl l='Edit this product'}" href="{url path='/admin/products/update' product_id=$ID}"><i class="glyphicon glyphicon-edit"></i></a>
@@ -445,7 +445,7 @@
{form_field form=$form field='title'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{$label} : </label>
{loop type="lang" name="default-lang" default_only="1"}
{loop type="lang" name="default-lang" default_only="1" backend_context="1"}
<div class="input-group">
<input type="text" id="{$label_attr.for}" required="required" name="{$name}" class="form-control" value="{$value}" title="{$label}" placeholder="{intl l='Title'}">
<span class="input-group-addon"><img src="{image file="assets/img/flags/{$CODE}.gif"}" alt="$TITLE" /></span>
@@ -463,6 +463,64 @@
</div>
{/form_field}
{form_field form=$form field='price'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{$label} : </label>
{loop type="currency" name="default-currency" default_only="1" backend_context="1"}
<div class="row">
<div class="col-lg-4">
<div class="input-group">
<input type="text" id="{$label_attr.for}" required="required" name="{$name}" class="col-lg-2 form-control" value="{$value}" title="{$label}" placeholder="{intl l='Product price'}">
<span class="input-group-addon">{$SYMBOL}</span>
</div>
</div>
</div>
<div class="help-block">{intl l='Enter here the product price in the default currency (%title)' title=$NAME}</div>
{form_field form=$form field='currency'}
<input type="hidden" name="{$name}" value="{$ID}" />
{/form_field}
{/loop}
</div>
{/form_field}
{form_field form=$form field='tax_rule'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{$label} : </label>
<div class="form-group">
<select id="{$label_attr.for}" required="required" name="{$name}" class="form-control">
<option value="">{intl l="Select a tax tule"}</option>
{loop name="tax" type="tax-rule" backend_context="1"}
<option value="{$ID}" {if $IS_DEFAULT}selected="selected"{/if}>{$TITLE}</option>
{/loop}
</select>
</div>
<div class="help-block">{intl l='Select here the tax applicable to this product'}</div>
</div>
{/form_field}
{form_field form=$form field='weight'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{$label}: </label>
<div class="row">
<div class="col-lg-4">
<div class="input-group">
<input type="text" id="{$label_attr.for}" required="required" name="{$name}" class="form-control" value="{$value}" title="{$label}" placeholder="{intl l='Product weight'}">
<span class="input-group-addon">{intl l="Kg"}</span>
</div>
</div>
</div>
<div class="help-block">{intl l='Enter here the product weight, in Kilogrammes'}</div>
</div>
{/form_field}
{form_field form=$form field='visible'}
<div class="form-group {if $error}has-error{/if}">
<div class="checkbox">
@@ -604,7 +662,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 +681,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'))

View File

@@ -163,7 +163,7 @@
<div class="col-md-6">
<div class="form-group">
<select name="folder_id" id="folder_id" class="form-control">
<option value="">Select a folder...</option>
<option value="">{intl l='Select a folder...'}</option>
{loop name="folders" type="folder-tree" folder="0" backend_context="1" lang="$edit_language_id"}
<option value="{$ID}" style="padding-left: {3 + $LEVEL * 20}px">{$TITLE}</option>
{/loop}
@@ -176,7 +176,7 @@
<div id="content_selector" class="hide">
<div class="input-group">
<select required="required" name="content_id" id="content_id" class="form-control">
<option value="">Select a folder content...</option>
<option value="">{intl l='Select a folder content...'}</option>
</select>
<span class="input-group-btn" id="content_add_button">
<button class="btn btn-default btn-primary action-btn" type="submit"><span class="glyphicon glyphicon-plus-sign"></span></button>

View File

@@ -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'))

View File

@@ -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 @@
</p>
<div class="alert alert-info">
{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."}
</div>
<div class="table-responsive">
<table class="table table-striped table-condensed table-left-aligned">
<thead>
@@ -122,7 +122,7 @@
</thead>
<tbody>
{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}
<tr>
<td>{$ID}</td>
@@ -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);

View File

@@ -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'))

View File

@@ -161,7 +161,7 @@
<div class="col-md-6">
<div class="form-group">
<select name="folder_id" id="folder_id" class="form-control">
<option value="">Select a folder...</option>
<option value="">{intl l='Select a folder...'}</option>
{loop name="folders" type="folder" backend_context="1" lang="$edit_language_id"}
<option value="{$ID}">{$TITLE}</option>
{/loop}
@@ -174,7 +174,7 @@
<div id="content_selector" class="hide">
<div class="input-group">
<select required="required" name="content_id" id="content_id" class="form-control">
<option value="">Select a folder content...</option>
<option value="">{intl l='Select a folder content...'}</option>
</select>
<span class="input-group-btn" id="content_add_button">
<button class="btn btn-default btn-primary action-btn" type="submit"><span class="glyphicon glyphicon-plus-sign"></span></button>

View File

@@ -7,8 +7,8 @@
{block name="main-content"}
<div class="folders">
<div id="wrapper" class="container">
<div id="wrapper" class="container">
{* include file="includes/folder-breadcrumb.html" *}
{module_include location='folders_top'}
@@ -20,7 +20,7 @@
<table class="table table-striped table-condensed" id="folder_list">
<caption>
{* display parent folder name, and get current folder ID *}
{loop name="folder_title" type="folder" visible="*" id=$parent}
{loop name="folder_title" type="folder" visible="*" id=$folder_id}
{intl l="Folders in %fold" fold=$TITLE}
{$fold_id = $ID}
{/loop}
@@ -28,11 +28,6 @@
{intl l="Top level folders"}
{/elseloop}
<td class="object-title">
<a href="{url path='admin/folders' parent=$ID}" title="{intl l='Browse this folder'}">
{$TITLE}
</a>
</td>
{module_include location='folder_list_caption'}
{loop type="auth" name="can_create" roles="ADMIN" permissions="admin.folders.create"}
@@ -50,7 +45,7 @@
current_order=$folder_order
order='id'
reverse_order='id_reverse'
path={url path='/admin/folders' parent=$parent}
path={url path='/admin/folders' id_folder=$folder_id}
request_parameter_name='folder_order'
label="{intl l='ID'}"
}
@@ -63,7 +58,7 @@
current_order=$folder_order
order='alpha'
reverse_order='alpha_reverse'
path={url path='/admin/folders' parent=$parent}
path={url path='/admin/folders' id_folder=$folder_id}
request_parameter_name='folder_order'
label="{intl l='Folder title'}"
}
@@ -76,7 +71,7 @@
current_order=$folder_order
order='visible'
reverse_order='visible_reverse'
path={url path='/admin/folders' parent=$parent}
path={url path='/admin/folders' id_folder=$folder_id}
request_parameter_name='folder_order'
label="{intl l='Online'}"
}
@@ -87,7 +82,7 @@
current_order=$folder_order
order='manual'
reverse_order='manual_reverse'
path={url path='/admin/folders' parent=$parent}
path={url path='/admin/folders' id_folder=$folder_id}
request_parameter_name='folder_order'
label="{intl l='Position'}"
}
@@ -98,18 +93,18 @@
</thead>
<tbody>
{loop name="folder_list" type="folder" visible="*" parent=$parent order=$folder_order backend_context="1" lang=$lang_id}
{loop name="folder_list" type="folder" visible="*" parent=$folder_id order=$folder_order backend_context="1" lang=$lang_id}
<tr>
<td>{$ID}</td>
<td>
{loop type="image" name="folder_image" source="folder" source_id="$ID" limit="1" width="50" height="50" resize_mode="crop" backend_context="1"}
<a href="{url path='admin/folders' parent=$ID}" title="{intl l='Browse this folder'}"><img class="img-thumbnail" src="{$IMAGE_URL}" alt="{$TITLE}" /></a>
<a href="{url path='admin/folder' folder_id=$ID}" title="{intl l='Browse this folder'}"><img class="img-thumbnail" src="{$IMAGE_URL}" alt="{$TITLE}" /></a>
{/loop}
</td>
<td class="object-title">
<a href="{url path='admin/folders' parent=$ID}" title="{intl l='Browse this folder'}">
<a href="{url path='admin/folder' folder_id=$ID}" title="{intl l='Browse this folder'}">
{$TITLE}
</a>
</td>
@@ -143,10 +138,10 @@
<td class="actions">
<div class="btn-group">
<a class="btn btn-default btn-xs" title="{intl l='Browse this folder'}" href="{url path='admin/folders' parent=$ID}"><i class="glyphicon glyphicon-folder-open"></i></a>
<a class="btn btn-default btn-xs" title="{intl l='Browse this folder'}" href="{url path='admin/folder' folder_id=$ID}"><i class="glyphicon glyphicon-folder-open"></i></a>
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.folders.edit"}
<a class="btn btn-default btn-xs" title="{intl l='Edit this folder'}" href="{url path="/admin/folders/update/{$ID}"}"><i class="glyphicon glyphicon-edit"></i></a>
<a class="btn btn-default btn-xs" title="{intl l='Edit this folder'}" href="{url path='/admin/folders/update' folder_id=$ID}"><i class="glyphicon glyphicon-edit"></i></a>
{/loop}
{loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.folders.delete"}
@@ -191,7 +186,7 @@
<table class="table table-striped table-condensed">
<caption>
{* display parent folder name *}
{loop name="folder_title" type="folder" visible="*" id=$parent}
{loop name="folder_title" type="folder" visible="*" id=$folder_id}
{intl l="Contents in %fold" fold=$TITLE}
{/loop}
@@ -214,18 +209,18 @@
current_order=$content_order
order='id'
reverse_order='id_reverse'
path={url path='/admin/folders' parent=$parent target='contents'}
path={url path='/admin/folders' id_folder=$folder_id target='contents'}
label="{intl l='ID'}"
}
<th>&nbsp;</th>
<th>&nbsp;</th>
<th class="object-title">
{admin_sortable_header
current_order=$content_order
order='alpha'
reverse_order='alpha_reverse'
path={url path='/admin/folders' parent=$parent target='contents'}
path={url path='/admin/folders' id_folder=$folder_id target='contents'}
label="{intl l='Content title'}"
}
@@ -236,7 +231,7 @@
current_order=$content_order
order='visible'
reverse_order='visible_reverse'
path={url path='/admin/folders' parent=$parent target='contents'}
path={url path='/admin/folders' id_folder=$folder_id target='contents'}
label="{intl l='Online'}"
}
</th>
@@ -246,7 +241,7 @@
current_order=$content_order
order='manual'
reverse_order='manual_reverse'
path={url path='/admin/folders' parent=$parent target='contents'}
path={url path='/admin/folders' id_folder=$folder_id target='contents'}
label="{intl l='Position'}"
}
</th>
@@ -256,13 +251,13 @@
</thead>
<tbody>
{loop name="content_list" type="content" visible="*" folder_default=$parent order=$content_order}
{loop name="content_list" type="content" visible="*" folder_default=$folder_id order=$content_order}
<tr>
<td>{$ID}</td>
<td>
{loop type="image" name="folder_image" source="content" source_id="$ID" limit="1" width="50" height="50" resize_mode="crop" backend_context="1"}
<a href="{url path="admin/content/update/$ID"}" title="{intl l='Edit this content'}">
<a href="{url path='admin/content/edit' id=$ID}" title="{intl l='Edit this content'}">
<img src="{$IMAGE_URL}" alt="{$TITLE}" />
</a>
{/loop}
@@ -344,11 +339,11 @@
{form_field form=$form field='success_url'}
{* on success, redirect to the edition page, _ID_ is replaced with the created object ID, see controller *}
<input type="hidden" name="{$name}" value="{url path='/admin/folders/update/_ID_'}" />
<input type="hidden" name="{$name}" value="{url path='/admin/folders/update' folder_id='_ID_'}" />
{/form_field}
{form_field form=$form field='parent'}
<input type="hidden" name="{$name}" value="{$parent}" />
<input type="hidden" name="{$name}" value="{$folder_id}" />
{/form_field}
{form_field form=$form field='title'}
@@ -412,16 +407,16 @@
{form_hidden_fields form=$form}
{* Be sure to get the folder_id, even if the form could not be validated *}
<input type="hidden" name="parent" value="{$parent}" />
<input type="hidden" name="folder_id" value="{$folder_id}" />
{form_field form=$form field='success_url'}
{* on success, redirect to the edition page, _ID_ is replaced with the created object ID, see controller *}
<input type="hidden" name="{$name}" value="{url path='/admin/content/update/_ID_' }" />
<input type="hidden" name="{$name}" value="{url path='/admin/contents/update' content_id='_ID_'}" />
{/form_field}
{form_field form=$form field='default_folder'}
<input type="hidden" name="{$name}" value="{$parent}" />
{/form_field}
<input type="hidden" name="{$name}" value="{$folder_id}" />
{/form_field}
{form_field form=$form field='title'}
<div class="form-group {if $error}has-error{/if}">
@@ -468,7 +463,7 @@
dialog_ok_label = {intl l="Create this content"}
form_action = {url path='/admin/content/create'}
form_action = {url path='/admin/contents/create'}
form_enctype = {form_enctype form=$form}
form_error_message = $form_error_message
}
@@ -498,7 +493,7 @@
{capture "content_delete_dialog"}
<input type="hidden" name="content_id" id="content_delete_id" value="" />
<input type="hidden" name="folder_id" value="{$parent}" />
<input type="hidden" name="folder_id" value="{$folder_id}" />
{module_include location='content_delete_form'}
@@ -585,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'))
@@ -604,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'))

View File

@@ -29,7 +29,7 @@ Parameters:
{$dialog_message nofilter}
</div>
<form method="{$form_method|default:POST}" action="{$form_action}" id="{$form_id}">
<form method="{$form_method|default:POST}" action="{$form_action}" id="{$form_id|default:"{$dialog_id}_form"}">
{$form_content nofilter}

View File

@@ -31,5 +31,5 @@ $('#{$dialog_id}').on('hidden.bs.modal', function() {
$("#{$dialog_id} .error").removeClass('error');
// Empty field values
$("#{$dialog_id} input[type=text]").val('');
$("#{$dialog_id} input[type=text], #{$dialog_id} select").val('');
});

View File

@@ -1,32 +1,50 @@
{*
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.
- show_currencies: true/false. If true, show the currency selection bar
- 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.
*}
<div class="row inner-toolbar">
<div class="col-md-6 inner-actions">
{* 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}
<div class="col-md-3 inner-actions">
<ul class="nav nav-pills">
{loop name="lang_list" type="lang" default_only={$default_only}}
{loop name="lang_list" type="lang"}
<li {if $ID == $edit_language_id}class="active"{/if}>
<a href="{url path=$current_url edit_language_id=$ID}" title="{intl l="Edit information in %lng" lng=$TITLE}">
<a href="{url path={$page_url|default:$current_url} edit_language_id=$ID}" title="{intl l='Edit information in %lng' lng=$TITLE}">
<img src="{image file="../assets/img/flags/{$CODE}.gif"}" alt="{intl l=$TITLE}" />
</a>
</li>
{/loop}
</ul>
</div>
</div>
<div class="col-md-6 inner-actions">
<div class="col-md-3 inner-actions">
{if $show_currencies == true}
<div class="row">
<div class="col-md-12">
<div class="button-group">
{loop name="currency_list" type="currency"}
<a class="btn btn-sm {if $ID == $edit_currency_id}btn-primary{else}btn-default{/if}" href="{url noamp=1 path='/admin/products/update' edit_currency_id=$ID product_id=$product_id current_tab='details'}" title="{intl l='Edit prices in %curr' curr=$NAME}">
{$SYMBOL}
</a>
{/loop}
</div>
</div>
</div>
{/if}
</div>
<div class="col-md-6 inner-actions">
{if $hide_submit_buttons != true}
<button type="submit" name="save_mode" value="stay" class="btn btn-default btn-success" title="{intl l='Save'}">{intl l='Save'} <span class="glyphicon glyphicon-ok"></span></button>
<button type="submit" name="save_mode" value="close" class="btn btn-default btn-info" title="{intl l='Save and close'}">{intl l='Save and close'} <span class="glyphicon glyphicon-remove"></span></button>
<button type="submit" name="save_mode" value="stay" class="btn btn-default btn-success" title="{intl l='Save'}">{intl l='Save'} <span class="glyphicon glyphicon-ok"></span></button>
<button type="submit" name="save_mode" value="close" class="btn btn-default btn-info" title="{intl l='Save and close'}">{intl l='Save and close'} <span class="glyphicon glyphicon-remove"></span></button>
{/if}
{if ! empty($close_url)}
<a href="{$close_url}" class="btn btn-default">{intl l='Close'} <span class="glyphicon glyphicon-remove"></span></a>
<a href="{$close_url}" class="btn btn-default">{intl l='Close'} <span class="glyphicon glyphicon-remove"></span></a>
{/if}
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,253 @@
<div class="form-container">
{form name="thelia.admin.product.details.modification"}
<form method="POST" action="{url path='/admin/products/details/save'}" {form_enctype form=$form} class="clearfix">
{include
file = "includes/inner-form-toolbar.html"
hide_submit_buttons = false
show_currencies = true
page_url = "{url path='/admin/products/update' product_id=$ID}"
close_url = "{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}"
}
{* Be sure to get the product ID, even if the form could not be validated *}
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="current_tab" value="details" />
{form_hidden_fields form=$form}
{form_field form=$form field='id'}
<input type="hidden" name="{$name}" value="{$value}" />
{/form_field}
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}" />
{/form_field}
{loop type="currency" name="product-currency" id=$edit_currency_id backend_context="1"}
{$currency_symbol = $SYMBOL}
{$currency_name = $NAME}
{form_field form=$form field='currency'}
<input type="hidden" name="{$name}" value="{$ID}" />
{/form_field}
{/loop}
<div class="row">
{* -- Pricing ------------------------------------------------------- *}
<div class="col-md-4">
<div class="well well-sm">
<p class="title title-without-tabs">{intl l='Pricing'}</p>
<p></p> <!-- LAME !!! FIXME -->
{form_field form=$form field='price'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{$label} : </label>
<div class="input-group">
<input type="text" id="{$label_attr.for}" required="required" name="{$name}" class="form-control" value="{$value}" title="{$label}" placeholder="{intl l='Product price'}">
<span class="input-group-addon">{$currency_symbol}</span>
</div>
</div>
{/form_field}
{form_field form=$form field='tax_rule'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{$label} : </label>
<div class="form-group">
<select id="{$label_attr.for}" required="required" name="{$name}" class="form-control">
<option value="">{intl l="Select a tax tule"}</option>
{loop name="tax" type="tax-rule" backend_context="1"}
<option value="{$ID}" {if $IS_DEFAULT}selected="selected"{/if}>{$TITLE}</option>
{/loop}
</select>
</div>
</div>
{/form_field}
{form_field form=$form field='price_with_tax'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{$label} : </label>
<div class="input-group">
<input type="text" id="{$label_attr.for}" required="required" name="{$name}" class="form-control" value="{$value}" title="{$label}" placeholder="{intl l='Product price'}">
<span class="input-group-addon">{$currency_symbol}</span>
</div>
</div>
{/form_field}
{module_include location='product_details_pricing_form'}
</div>
</div>
{* -- Promotion ------------------------------------------------- *}
<div class="col-md-4">
<div class="well well-sm">
<p class="title title-without-tabs">{intl l='Promotion'}</p>
{form_field form=$form field='sale_price'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{$label} : </label>
<div class="input-group">
<input type="text" id="{$label_attr.for}" required="required" name="{$name}" class="form-control" value="{$value}" title="{$label}" placeholder="{intl l='Product price'}">
<span class="input-group-addon">{$currency_symbol}</span>
</div>
</div>
{/form_field}
{form_field form=$form field='onsale'}
<div class="form-group {if $error}has-error{/if}">
<div class="checkbox">
<label>
<input type="checkbox" id="{$label_attr.for}" name="{$name}" value="1" {if $value != 0}checked="checked"{/if}>
{$label}
</label>
</div>
</div>
{/form_field}
{form_field form=$form field='isnew'}
<div class="form-group {if $error}has-error{/if}">
<div class="checkbox">
<label>
<input type="checkbox" id="{$label_attr.for}" name="{$name}" value="1" {if $value != 0}checked="checked"{/if}>
{$label}
</label>
</div>
</div>
{/form_field}
{module_include location='product_details_promotion_form'}
</div>
</div>
{* -- Shipping -------------------------------------------------- *}
<div class="col-md-4">
<div class="well well-sm">
<p class="title title-without-tabs">{intl l='Shipping'}</p>
{form_field form=$form field='weight'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{$label} : </label>
<div class="input-group">
<input type="text" id="{$label_attr.for}" required="required" name="{$name}" class="form-control" value="{$value}" title="{$label}" placeholder="{intl l='Product weight'}">
<span class="input-group-addon">{intl l="Kg"}</span>
</div>
</div>
{/form_field}
{module_include location='product_details_shipping_form'}
<p class="title title-without-tabs">{intl l='Quantity'}</p>
{form_field form=$form field='quantity'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{$label} : </label>
<div class="form-group">
<input type="text" id="{$label_attr.for}" required="required" name="{$name}" class="form-control" value="{$value}" title="{$label}" placeholder="{intl l='Current quantity'}">
</div>
</div>
{/form_field}
{module_include location='product_details_quantity_form'}
</div>
</div>
</div>
</form>
{/form}
{* -- Attribute combinations -------------------------------------------- *}
<div class="row">
<div class="col-md-12">
<p class="title title-without-tabs">{intl l='Attribute Combinations'}</p>
{module_include location='product_before_combinations'}
{ifloop rel="product-attributes"}
<form method="POST" action="{url path='/admin/products/combinations/save'}" {form_enctype form=$form} class="clearfix">
<div class="well well-sm">
<p class="title title-without-tabs">{intl l='Create a new combination'}</p>
<div class="form-group">
<label class="control-label">{intl l="Attribute"} : </label>
<select required="required" name="attribute_id" id="attribute_id" class="form-control">
<option value="">{intl l='Select an attribute...'}</option>
{loop name="product-attributes" type="attribute" product=$product_id backend_context="1" lang=$edit_language_id}
<option value="{$ID}">{$TITLE}</option>
{/loop}
</select>
<span class="help-block">{intl l='Select an attribute and click (+) to view available values'}</span>
</div>
<div id="attribute_value_selector" class="hide">
<div class="input-group">
{* <label class="control-label">{intl l="Attribute values"} : </label> *}
<select required="required" name="attribute_value_id" id="attribute_value_id" class="form-control">
<option value="">{intl l='Select an attribute value...'}</option>
</select>
<span class="input-group-btn" id="add_attr_value_button">
<button class="btn btn-default btn-primary action-btn add-value-to-combination" type="button"><span class="glyphicon glyphicon-plus-sign"></span></button>
</span>
</div>
<span class="help-block">{intl l='Select a value click (+) to add it to the combination'}</span>
</div>
<div id="attribute_value_selector_empty" class="hide">
<div class="alert alert-info">
{intl l="No available value for this attribute"}
</div>
</div>
<div class="form-group">
<div class="alert alert-danger hide" id="combination_attributes_error"></div>
<select multiple="multiple" size="5" name="combination_attributes" id="combination_attributes" class="form-control">
</select>
<div class="help-block">
{intl l='To remove a value from the combination, select it and click "remove"'}
<div class="pull-right">
<button class="btn btn-info btn-xs remove-value-from-combination" type="button">
{intl l="Remove selected value"} <span class="glyphicon glyphicon-minus-sign"></span>
</button>
</div>
</div>
</div>
</div>
</form>
{/ifloop}
{elseloop rel="product-attributes"}
<div class="alert alert-info">
{intl l="No attributes are attached to this product."}
</div>
{/elseloop}
{module_include location='product_after_combinations'}
</div> {* com *}
</div> {* row *}
</div>

View File

@@ -0,0 +1,112 @@
<div class="form-container">
{form name="thelia.admin.product.modification"}
<form method="POST" action="{url path='/admin/products/save'}" {form_enctype form=$form} class="clearfix">
{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 *}
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="current_tab" value="general" />
{form_hidden_fields form=$form}
{form_field form=$form field='id'}
<input type="hidden" name="{$name}" value="{$value}" />
{/form_field}
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}" />
{/form_field}
{form_field form=$form field='locale'}
<input type="hidden" name="{$name}" value="{$edit_language_locale}" />
{/form_field}
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
<div class="form-group">
<label class="control-label">
{intl l='Product reference'} :
</label>
<div class="well well-sm">{$REF}</div>
{form_field form=$form field='ref'}
<input type="hidden" name="{$name}" value="{$value}" />
{/form_field}
</div>
{include file="includes/standard-description-form-fields.html"}
{form_field form=$form field='url'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">
{intl l="{$label}"} :
</label>
<input type="text" id="{$label_attr.for}" required="required" name="{$name}" value="{$value}" title="{intl l='Rewritten URL'}" placeholder="{intl l='Rewriten URL'}" class="form-control">
</div>
{/form_field}
<div class="row">
<div class="col-md-6">
{form_field form=$form field='default_category'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">
{intl l="{$label}"} :
</label>
<select id="{$label_attr.for}" required="required" name="{$name}" class="form-control">
<option value="0">{intl l="Top level"}</option>
{loop name="cat-parent" type="category-tree" category="0" visible="*" product="0"}
<option value="{$ID}" style="padding-left: {3 + $LEVEL * 20}px" {if $DEFAULT_CATEGORY == $ID}selected="selected"{/if}>{$TITLE}</option>
{/loop}
</select>
<span class="help-block">{intl l='You can attach this product to more categories in the details tab.'}</span>
</div>
{/form_field}
</div>
<div class="col-md-6">
{form_field form=$form field='visible'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l='Visibility'}</label>
<div class="checkbox">
<label>
<input type="checkbox" id="{$label_attr.for}" name="{$name}" value="1" {if $value != 0}checked="checked"{/if}>
{$label}
</label>
</div>
</div>
{/form_field}
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="control-group">
<label>&nbsp;</label>
<div class="controls">
<p>{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}"}</p>
</div>
</div>
</div>
</div>
</form>
{/form}
</div>

View File

@@ -1,4 +1,6 @@
{* The standard description fields, used by many Thelia objects *}
{*
The standard description fields, used by many Thelia objects
*}
{form_field form=$form field='title'}
<div class="form-group {if $error}has-error{/if}">
@@ -22,7 +24,7 @@
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">
{intl l="{$label}"} :
<span class="label-help-block">{intl l="The détailed description."}</span>
<span class="label-help-block">{intl l="The detailed description."}</span>
</label>
<textarea name="{$name}" id="{$label_attr.for}" rows="10" class="form-control wysiwyg">{$value}</textarea>

View File

@@ -6,6 +6,7 @@
{block name="main-content"}
<div class="catalog edit-product">
<div id="wrapper" class="container">
{include file="includes/catalog-breadcrumb.html" editing_category="false" editing_product="true"}
@@ -40,354 +41,60 @@
<div class="col-md-12">
<ul class="nav nav-tabs" id="tabbed-menu">
<li {if $current_tab == 'general'}class="active"{/if}><a href="#general" data-toggle="tab">{intl l="General description"}</a></li>
<li {if $current_tab == 'details'}class="active"{/if}><a href="#details" data-toggle="tab">{intl l="Details"}</a></li>
<li {if $current_tab == 'images'}class="active"{/if}><a href="#images" data-toggle="tab">{intl l="Images"}</a></li>
<li {if $current_tab == 'documents'}class="active"{/if}><a href="#documents" data-toggle="tab">{intl l="Documents"}</a></li>
<li {if $current_tab == 'modules'}class="active"{/if}><a href="#modules" data-toggle="tab">{intl l="Modules"}</a></li>
<li>
<a href="#general"
{* data-href="{url path='/admin/products/general/tab' product_id=$product_id}" *}
data-toggle="tab">{intl l="General"}</a>
</li>
<li>
<a href="#details" data-toggle="tab">{intl l="Details"}</a>
</li>
<li><a href="#attributes"
data-href="{url path='/admin/products/attributes/tab' product_id=$product_id}"
data-toggle="tab">{intl l="Attributes &amp; Features"}</a>
</li>
<li>
<a href="#related"
data-href="{url path='/admin/products/related/tab' folder_id=$folder_id accessory_category_id=$accessory_category_id product_id=$product_id}"
data-toggle="tab">{intl l="Associations"}</a>
</li>
<li><a href="#images" data-toggle="tab">{intl l="Images"}</a></li>
<li><a href="#documents" data-toggle="tab">{intl l="Documents"}</a></li>
<li><a href="#modules" data-toggle="tab">{intl l="Modules"}</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane fade {if $current_tab == 'general'}active in{/if}" id="general">
<div class="form-container">
{form name="thelia.admin.product.modification"}
<form method="POST" action="{url path='/admin/products/save'}" {form_enctype form=$form} class="clearfix">
{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 *}
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="current_tab" value="general" />
{form_hidden_fields form=$form}
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path='/admin/product' product_id={$product_d}}" />
{/form_field}
{form_field form=$form field='locale'}
<input type="hidden" name="{$name}" value="{$edit_language_locale}" />
{/form_field}
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
<div class="form-group">
<label for="product_ref" class="control-label">
{intl l='Product reference'} :
</label>
<div class="well well-sm">{$REF}</div>
</div>
{include file="includes/standard-description-form-fields.html"}
{form_field form=$form field='url'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">
{intl l="{$label}"} :
</label>
<input type="text" id="{$label_attr.for}" required="required" name="{$name}" value="{$value}" title="{intl l='Rewritten URL'}" placeholder="{intl l='Rewriten URL'}" class="form-control">
</div>
{/form_field}
<div class="row">
<div class="col-md-6">
{form_field form=$form field='default_category'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">
{intl l="{$label}"} :
</label>
<select id="{$label_attr.for}" required="required" name="{$name}" class="form-control">
<option value="0">{intl l="Top level"}</option>
{loop name="cat-parent" type="category-tree" category="0" visible="*" product="0"}
<option value="{$ID}" style="padding-left: {3 + $LEVEL * 20}px" {if $DEFAULT_CATEGORY == $ID}selected="selected"{/if} {if $product_id == $ID}disabled="disabled"{/if}>{$TITLE}</option>
{/loop}
</select>
<span class="help-block">{intl l='You can attach this product to more categories in the details tab.'}</span>
</div>
{/form_field}
</div>
<div class="col-md-6">
{form_field form=$form field='visible'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l='Visibility'}</label>
<div class="checkbox">
<label>
<input type="checkbox" id="{$label_attr.for}" name="{$name}" value="1" {if $value != 0}checked="checked"{/if}>
{$label}
</label>
</div>
</div>
{/form_field}
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="control-group">
<lablel>&nbsp;</lablel>
<div class="controls">
<p>{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}"}</p>
</div>
</div>
</div>
</div>
</form>
{/form}
</div>
<div class="tab-pane fade" id="general">
{include file="includes/product-general-tab.html"}
</div>
<div class="tab-pane fade {if $current_tab == 'details'}active in{/if}" id="details">
<div class="form-container">
<div class="tab-pane fade" id="details">
{include file="includes/product-details-tab.html"}
</div>
{include
file="includes/inner-form-toolbar.html"
hide_submit_buttons=true
close_url="{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}"
}
<div class="tab-pane fade" id="attributes">
<div class="text-center"><span class="loading">{intl l="Please wait, loading"}</span></div>
</div>
{* -- Begin related content management -- *}
<div class="col-md-6">
<div class="form-group">
<form action="{url path='/admin/products/related-content/add'}" id="related_content_form">
<p class="title title-without-tabs">{intl l='Related content'}</p>
<p>{intl l='You can attach here some content to this product'}</p>
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="current_tab" value="details" />
{ifloop rel="folders"}
<div class="form-group">
<select name="folder_id" id="folder_id" class="form-control">
<option value="">Select a folder...</option>
{loop name="folders" type="folder-tree" folder="0" backend_context="1" lang="$edit_language_id"}
<option value="{$ID}" style="padding-left: {3 + $LEVEL * 20}px">{$TITLE}</option>
{/loop}
</select>
<span class="help-block">{intl l='Select a folder to get its content'}</span>
</div>
<div id="content_selector" class="hide">
<div class="input-group">
<select required="required" name="content_id" id="content_id" class="form-control">
<option value="">Select a folder content...</option>
</select>
<span class="input-group-btn" id="content_add_button">
<button class="btn btn-default btn-primary action-btn" type="submit"><span class="glyphicon glyphicon-plus-sign"></span></button>
</span>
</div>
<span class="help-block">{intl l='Select a content and click (+) to add it to this product'}</span>
</div>
<div id="content_selector_empty" class="hide">
<div class="alert alert-info">
{intl l="No available content for this folder"}
</div>
</div>
{/ifloop}
{elseloop rel="folders"}
<div class="alert alert-info">{intl l="No folders found"}</div>
{/elseloop}
</form>
</div>
<table class="table table-striped table-condensed table-left-aligned">
<thead>
<tr>
<th>{intl l='ID'}</th>
<th>{intl l='Content title'}</th>
{module_include location='product_contents_table_header'}
<th class="actions">{intl l="Actions"}</th>
</tr>
</thead>
<tbody>
{loop name="assigned_contents" type="associated_content" product="$product_id" backend_context="1" lang="$edit_language_id"}
<tr>
<td>{$ID}</td>
<td>
{$TITLE}
</td>
{module_include location='product_contents_table_row'}
<td class="actions">
<div class="btn-group">
{loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.product.content.delete"}
<a class="btn btn-default btn-xs delete-content" title="{intl l='Delete this content'}" href="#delete_content_dialog" data-id="{$ID}" data-toggle="modal">
<span class="glyphicon glyphicon-trash"></span>
</a>
{/loop}
</div>
</td>
</tr>
{/loop}
{elseloop rel="assigned_contents"}
<tr>
<td colspan="3">
<div class="alert alert-info">
{intl l="This product contains no contents"}
</div>
</td>
</tr>
{/elseloop}
</tbody>
</table>
</div>
{* -- End related content management ---- *}
{* -- Begin accessories management ------ *}
<div class="col-md-6">
<div class="form-group">
<form action="{url path='/admin/products/accessory/add'}" id="accessory_form">
<p class="title title-without-tabs">{intl l='Product accessories'}</p>
<p>{intl l='Define here this product\'s accessories'}</p>
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="current_tab" value="details" />
{ifloop rel="categories"}
<div class="form-group">
<select name="accessory_category_id" id="accessory_category_id" class="form-control">
<option value="">Select a category...</option>
{loop name="categories" type="category-tree" category="0" backend_context="1" lang="$edit_language_id"}
<option value="{$ID}" style="padding-left: {3 + $LEVEL * 20}px">{$TITLE}</option>
{/loop}
</select>
<span class="help-block">{intl l='Select a category to get its products'}</span>
</div>
<div id="accessory_selector" class="hide">
<div class="input-group">
<select required="required" name="accessory_id" id="accessory_id" class="form-control">
<option value="">Select a product...</option>
</select>
<span class="input-group-btn" id="accessory_add_button">
<button class="btn btn-default btn-primary action-btn" type="submit"><span class="glyphicon glyphicon-plus-sign"></span></button>
</span>
</div>
<span class="help-block">{intl l='Select a product and click (+) to add it as an accessory'}</span>
</div>
<div id="accessory_selector_empty" class="hide">
<div class="alert alert-info">
{intl l="No available product in this category"}
</div>
</div>
{/ifloop}
{elseloop rel="categories"}
<div class="alert alert-info">{intl l="No categories found"}</div>
{/elseloop}
</form>
</div>
<table class="table table-striped table-condensed table-left-aligned">
<thead>
<tr>
<th>{intl l='ID'}</th>
<th>{intl l='Accessory title'}</th>
<th class="text-center">{intl l='Position'}</th>
{module_include location='product_accessories_table_header'}
<th class="actions">{intl l="Actions"}</th>
</tr>
</thead>
<tbody>
{loop name="assigned_accessories" order="accessory" type="accessory" product="$product_id" backend_context="1" lang="$edit_language_id"}
<tr>
<td>{$ID}</td>
<td>
{$TITLE}
</td>
<td class="text-center">
{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
}
</td>
{module_include location='product_accessories_table_row'}
<td class="actions">
<div class="btn-group">
{loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.product.accessory.delete"}
<a class="btn btn-default btn-xs delete-accessory" title="{intl l='Delete this accessory'}" href="#delete_accessory_dialog" data-id="{$ID}" data-toggle="modal">
<span class="glyphicon glyphicon-trash"></span>
</a>
{/loop}
</div>
</td>
</tr>
{/loop}
{elseloop rel="assigned_accessories"}
<tr>
<td colspan="4">
<div class="alert alert-info">
{intl l="This product contains no accessories"}
</div>
</td>
</tr>
{/elseloop}
</tbody>
</table>
</div>
{* -- End accessories management -------- *}
</div>
<div class="tab-pane fade" id="related">
<div class="text-center"><span class="loading">{intl l="Please wait, loading"}</span></div>
</div>
<div class="tab-pane fade {if $current_tab == 'images'}active in{/if}" id="images">
{include file='includes/image-upload-form.html' imageType='product' parentId=$product_id}
<div class="tab-pane fade" id="images">
<div class="text-center"><span class="loading">{intl l="Please wait, loading"}</span></div>
</div>
<div class="tab-pane fade {if $current_tab == 'documents'}active in{/if}" id="documents">
<div class="tab-pane fade" id="documents">
<div class="text-center"><span class="loading">{intl l="Please wait, loading"}</span></div>
</div>
<div class="tab-pane fade {if $current_tab == 'modules'}active in{/if}" id="modules">
<div class="tab-pane fade" id="modules">
<div class="text-center"><span class="loading">{intl l="Please wait, loading"}</span></div>
</div>
</div>
</div>
@@ -398,209 +105,132 @@
</div>
</div>
{* Delete related content confirmation dialog *}
{capture "delete_content_dialog"}
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="content_id" id="content_delete_id" value="" />
<input type="hidden" name="folder_id" id="folder_delete_id" value="" />
<input type="hidden" name="current_tab" value="details" />
{/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"}
<input type="hidden" name="product_id" value="{$product_id}" />
<input type="hidden" name="accessory_id" id="accessory_delete_id" value="" />
<input type="hidden" name="accessory_category_id" id="accessory_category_delete_id" value="" />
<input type="hidden" name="current_tab" value="details" />
{/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"}
{javascripts file='assets/js/dropzone.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/image-upload.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap-editable/bootstrap-editable.js'}
<script src="{$asset_url}"></script>
{/javascripts}
{javascripts file='assets/js/bootstrap-editable/bootstrap-editable.js'}
<script src="{$asset_url}"></script>
{/javascripts}
<script src="{url file='/tinymce/tinymce.min.js'}"></script>
<script>
tinymce.init({
selector: ".wysiwyg",
theme: "modern",
menubar : false,
language: "",
plugins: [
"advlist autolink link image lists charmap print preview hr anchor pagebreak",
"searchreplace wordcount visualblocks visualchars insertdatetime media nonbreaking",
"table contextmenu directionality emoticons paste textcolor filemanager"
],
toolbar1: "undo redo | bold italic underline | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | styleselect | filemanager | link unlink anchor | image media | forecolor backcolor | print preview code ",
image_advtab: true ,
external_filemanager_path:"{url file='/tinymce/plugins/filemanager/'}'",
filemanager_title:"{intl l='Files manager'}" ,
external_plugins: { "filemanager" : "{url file='/tinymce/plugins/filemanager/plugin.min.js'}"}
});
</script>
<script src="{url file='/tinymce/tinymce.min.js'}"></script>
<script>
tinymce.init({
selector: ".wysiwyg",
theme: "modern",
menubar : false,
language: "",
plugins: [
"advlist autolink link image lists charmap print preview hr anchor pagebreak",
"searchreplace wordcount visualblocks visualchars insertdatetime media nonbreaking",
"table contextmenu directionality emoticons paste textcolor filemanager"
],
toolbar1: "undo redo | bold italic underline | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | styleselect | filemanager | link unlink anchor | image media | forecolor backcolor | print preview code ",
image_advtab: true ,
external_filemanager_path:"{url file='/tinymce/plugins/filemanager/'}'",
filemanager_title:"{intl l='Files manager'}" ,
external_plugins: { "filemanager" : "{url file='/tinymce/plugins/filemanager/plugin.min.js'}"}
});
</script>
<script>
$(function() {
<script>
$(function() {
$('.use_default_rewriten_url').click(function(ev) {
alert("Not functionnal");
// Atomatic ajax tab load, if data-href is defined.
$('.nav-tabs a[data-href]').on('shown.bs.tab', function(ev) {
var zis = $(this);
$(zis.attr('href')).load(zis.data('href'));
});
ev.preventDefault();
});
// Load active tab
$('.nav-tabs a[href="#{$current_tab}"]').trigger("click");
// Set proper content ID in delete content from
$('a.delete-content').click(function(ev) {
$('#content_delete_id').val($(this).data('id'));
$('#folder_delete_id').val($('#folder_id').val());
});
// -- Product details management tab ---------------------------------------
// Set proper content ID in accessory delete from
$('a.delete-accessory').click(function(ev) {
$('#accessory_delete_id').val($(this).data('id'));
$('#accessory_category_delete_id').val($('#accessory_category_id').val());
});
// Load value on attribute selection
$('#attribute_id').change(function(event) {
var val = $(this).val();
if (val != "") {
$.ajax({
url : '{url path="/admin/product/$product_id/attribute-values/"}' + $(this).val() + '.xml',
type : 'get',
dataType : 'json',
success : function(json) {
$('#attribute_value_id :not(:first-child)').remove();
var have_content = false;
$.each(json, function(idx, value) {
$('#attribute_value_id').append($('<option>').text(value.title).attr('value', value.id));
have_content = true; // Lame...
});
if (have_content) {
$('#attribute_value_selector_empty').addClass('hide');
$('#attribute_value_selector').removeClass('hide');
}
else {
$('#attribute_value_selector_empty').removeClass('hide');
$('#attribute_value_selector').addClass('hide');
}
}
});
}
else {
$('#attribute_value_selector_empty').addClass('hide');
$('#attribute_value_selector').addClass('hide');
}
});
// Add selected value to the combination
$('.add-value-to-combination').click(function(event) {
// Hide error message
$('#combination_attributes_error').text('').addClass('hide');
// Select all elements
$('#combination_attributes option').prop('selected', 'selected');
$.ajax({
url : '{url path="/admin/product/$product_id/add-attribute-value-to-combination/"}'
+ $('#attribute_value_id').val()
+ '/'
+ $('#combination_attributes').val()
+ '.xml',
type : 'get',
dataType : 'json',
success : function(json) {
$('#combination_attributes option').remove();
var have_content = false;
$.each(json, function(idx, value) {
if (idx != 'error')
$('#combination_attributes').append($('<option>').text(value.title).attr('value', value.id));
});
if (json.error)
$('#combination_attributes_error').text(json.error).removeClass('hide');
$('#attribute_id').val('').change();
}
});
event.preventDefault();
});
// Remove selected value from combination
$('.remove-value-from-combination').click(function() {
$('#combination_attributes option:selected').remove();
event.preventDefault();
});
});
</script>
// Load content on folder selection
$('#folder_id').change(function(event) {
var val = $(this).val();
if (val != "") {
$.ajax({
url : '{url path="/admin/product/$product_id/available-related-content/"}' + $(this).val() + '.xml',
type : 'get',
dataType : 'json',
success : function(json) {
$('#content_id :not(:first-child)').remove();
var have_content = false;
$.each(json, function(idx, value) {
$('#content_id').append($('<option>').text(value.title).attr('value', value.id));
have_content = true; // Lame...
});
if (have_content) {
$('#content_selector_empty').addClass('hide');
$('#content_selector').removeClass('hide');
}
else {
$('#content_selector_empty').removeClass('hide');
$('#content_selector').addClass('hide');
}
}
});
}
else {
$('#content_selector_empty').addClass('hide');
$('#content_selector').addClass('hide');
}
});
// Load content on folder selection
$('#accessory_category_id').change(function(event) {
var val = $(this).val();
if (val != "") {
$.ajax({
url : '{url path="/admin/product/$product_id/available-accessories/"}' + $(this).val() + '.xml',
type : 'get',
dataType : 'json',
success : function(json) {
$('#accessory_id :not(:first-child)').remove();
var have_content = false;
$.each(json, function(idx, value) {
$('#accessory_id').append($('<option>').text(value.title).attr('value', value.id));
have_content = true; // Lame...
});
if (have_content) {
$('#accessory_selector_empty').addClass('hide');
$('#accessory_selector').removeClass('hide');
}
else {
$('#accessory_selector_empty').removeClass('hide');
$('#accessory_selector').addClass('hide');
}
}
});
}
else {
$('#accessory_selector_empty').addClass('hide');
$('#accessory_selector').addClass('hide');
}
});
{* Inline editing of accessory position using bootstrap-editable *}
$('.accessoryPositionChange').editable({
type : 'text',
title : '{intl l="Enter new accessory position"}',
mode : 'popup',
inputclass : 'input-mini',
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__'}";
// Perform subtitutions
url = url.replace('__ID__', $(this).data('id')).replace('__POS__', newValue);
// Reload the page
location.href = url;
}
});
// Initialize folder (id={$folder_id}) select value
{if $folder_id != 0}
$('#folder_id').val("{$folder_id}").change();
{/if}
// Initialize folder (id={$folder_id}) select value
{if $accessory_category_id != 0}
$('#accessory_category_id').val("{$accessory_category_id}").change();
{/if}
});
</script>
{/block}

View File

@@ -59,30 +59,32 @@
{/form}
</div>
</div>
</div>
<div class="col-md-12">
<div class="form-container">
<div class="col-md-6">
<div class="row">
<div class="form-container">
<div class="col-md-6">
<div class="well well-sm">
<p class="title title-without-tabs">{intl l='Attributes'}</p>
<p>Manage attributes included in this product templates</p>
<div id="attribute_list_management">
<div class="loading"></div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="col-md-6">
<div class="well well-sm">
<p class="title title-without-tabs">{intl l='Features'}</p>
<p>Manage features included in this product templates</p>
<div id="feature_list_management">
<div class="loading"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -106,10 +108,14 @@
{block name="javascript-initialization"}
{javascripts file='assets/js/bootstrap-editable/bootstrap-editable.js'}
<script src="{$asset_url}"></script>
{/javascripts}
<script>
$(function() {
$('#feature_list_management').load("{url path='/admin/configuration/templates/features/list' template_id=$template_id}");
$('#attribute_list_management').load("{url path='/admin/configuration/templates/attributes/list' template_id=$template_id}");
$('#feature_list_management').load("{url noamp='1' path='/admin/configuration/templates/features/list' template_id=$template_id}");
$('#attribute_list_management').load("{url noamp='1' path='/admin/configuration/templates/attributes/list' template_id=$template_id}");
});
</script>
{/block}

View File

@@ -25,7 +25,7 @@
{if ! empty($general_error) }
<div class="alert alert-danger">{$general_error}</div>
{/if}
<div class="table-responsive">
<table class="table table-striped table-condensed table-left-aligned">
<caption>
@@ -194,10 +194,6 @@
{block name="javascript-initialization"}
{javascripts file='assets/js/bootstrap-editable/bootstrap-editable.js'}
<script src="{$asset_url}"></script>
{/javascripts}
<script>
$(function() {