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

Conflicts:
	templates/admin/default/assets/css/admin.less
This commit is contained in:
mespeche
2013-08-30 15:50:40 +02:00
34 changed files with 1685 additions and 212 deletions

View File

@@ -25,10 +25,14 @@ namespace Thelia\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\ActionEvent;
use Thelia\Core\Event\Coupon\CouponCreateEvent;
use Thelia\Core\Event\Coupon\CouponDisableEvent;
use Thelia\Core\Event\Coupon\CouponEnableEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\Category as CategoryModel;
use Thelia\Form\CategoryCreationForm;
use Thelia\Core\Event\CategoryEvent;
use Thelia\Model\CouponQuery;
use Thelia\Tools\Redirect;
use Thelia\Model\CategoryQuery;
use Thelia\Model\AdminLog;
@@ -40,8 +44,116 @@ use Propel\Runtime\Propel;
use Thelia\Model\Map\CategoryTableMap;
use Propel\Runtime\Exception\PropelException;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Process Coupon Events
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class Coupon extends BaseAction implements EventSubscriberInterface
{
/**
* Create a Coupon if a Coupon creation attempt is found
*
* @param CouponCreateEvent $event Coupon creation Event
*/
public function create(CouponCreateEvent $event)
{
$this->checkAuth("ADMIN", "admin.coupon.create");
$this->dispatch(
TheliaEvents::BEFORE_CREATE_COUPON,
$event
);
$event->getCreatedCoupon()->save();
$this->dispatch(
TheliaEvents::AFTER_CREATE_COUPON,
$event
);
}
/**
* Edit a Coupon if a Coupon edition attempt is found
*
* @param CouponEditEvent $event Coupon edition Event
*/
public function edit(CouponEditEvent $event)
{
$this->checkAuth("ADMIN", "admin.coupon.edit");
$this->dispatch(
TheliaEvents::BEFORE_EDIT_COUPON,
$event
);
$couponToUpdate = CouponQuery::create()->findPk($event->getId());
if ($couponToUpdate !== null) {
$event->getCreatedCoupon()->save();
}
$this->dispatch(
TheliaEvents::AFTER_EDIT_COUPON,
$event
);
}
/**
* Disable a Coupon if a Coupon disable attempt is found
*
* @param CouponDisableEvent $event Coupon disable Event
*/
public function disable(CouponDisableEvent $event)
{
$this->checkAuth("ADMIN", "admin.coupon.disable");
$couponToUpdate = CouponQuery::create()->findPk($event->getId());
if ($couponToUpdate !== null) {
$couponToUpdate->setIsEnabled(0);
$event->getDispatcher()->dispatch(
TheliaEvents::BEFORE_DISABLE_COUPON, $event
);
$couponToUpdate->save();
$event->getDispatcher()->dispatch(
TheliaEvents::AFTER_DISABLE_COUPON, $event
);
}
}
/**
* Enable a Coupon if a Coupon enable attempt is found
*
* @param CouponEnableEvent $event Coupon enable Event
*/
public function enable(CouponEnableEvent $event)
{
$this->checkAuth("ADMIN", "admin.coupon.enable");
$couponToUpdate = CouponQuery::create()->findPk($event->getId());
if ($couponToUpdate !== null) {
$couponToUpdate->setIsEnabled(1);
$event->getDispatcher()->dispatch(
TheliaEvents::BEFORE_ENABLE_COUPON, $event
);
$couponToUpdate->save();
$event->getDispatcher()->dispatch(
TheliaEvents::AFTER_ENABLE_COUPON, $event
);
}
}
/**
* Returns an array of event names this subscriber listens to.

View File

@@ -89,7 +89,7 @@ class CategoryController extends BaseAdminController
$categoryDeletionForm = new CategoryDeletionForm($this->getRequest());
$data = $this->validateForm($categoryDeletionForm, "POST")->getData();
var_dump($data);
$categoryDeleteEvent = new CategoryDeleteEvent($data['category_id']);
$this->dispatch(TheliaEvents::CATEGORY_DELETE, $categoryDeleteEvent);
@@ -151,8 +151,8 @@ var_dump($data);
protected function positionDown($args)
{
$event = new CategoryChangePositionEvent(
$this->getRequest()->get('category_id', 0),
CategoryChangePositionEvent::POSITION_DOWN
$this->getRequest()->get('category_id', 0),
CategoryChangePositionEvent::POSITION_DOWN
);
$this->dispatch(TheliaEvents::CATEGORY_CHANGE_POSITION, $event);

View File

@@ -23,8 +23,14 @@
namespace Thelia\Controller\Admin;
use Thelia\Core\Event\Coupon\CouponCreateEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Security\Exception\AuthenticationException;
use Thelia\Core\Security\Exception\AuthorizationException;
use Thelia\Coupon\CouponRuleCollection;
use Thelia\Form\CouponCreationForm;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Model\Coupon;
/**
* Created by JetBrains PhpStorm.
@@ -74,7 +80,46 @@ class CouponController extends BaseAdminController
{
$this->checkAuth("ADMIN", "admin.coupon.view");
return $this->render('coupon/edit', $args);
if ($this->getRequest()->isMethod('POST')) {
try {
$couponCreationForm = new CouponCreationForm($this->getRequest());
$couponBeingCreated = $this->buildCouponFromForm(
$this->validateForm($couponCreationForm, "POST")->getData()
);
$couponCreateEvent = new CouponCreateEvent(
$couponBeingCreated
);
$this->dispatch(
TheliaEvents::CREATE_COUPON,
$couponCreateEvent
);
$this->adminLogAppend(
sprintf(
'Coupon %s (ID %s) created',
$couponBeingCreated->getTitle(),
$couponBeingCreated->getId()
)
);
// @todo redirect if successful
} catch (FormValidationException $e) {
$couponCreationForm->setErrorMessage($e->getMessage());
$this->getParserContext()->setErrorForm($couponCreationForm);
} catch (\Exception $e) {
Tlog::getInstance()->error(
sprintf(
"Failed to create coupon: %s",
$e->getMessage()
)
);
$this->getParserContext()->setGeneralError($e->getMessage());
}
} else {
}
return $this->render('coupon/edit', array());
}
/**
@@ -114,7 +159,6 @@ class CouponController extends BaseAdminController
*/
public function processAction()
{
var_dump($this->getRequest()->attributes);
// Get the current action
$action = $this->getRequest()->get('action', 'browse');
@@ -146,4 +190,39 @@ class CouponController extends BaseAdminController
// We did not recognized the action -> return a 404 page
return $this->pageNotFound();
}
/**
* Build a Coupon from its form
*
* @param array $data Form data
*
* @return Coupon
*/
protected function buildCouponFromForm(array $data)
{
$couponBeingCreated = new Coupon();
$couponBeingCreated->setCode($data["code"]);
$couponBeingCreated->setType($data["type"]);
$couponBeingCreated->setTitle($data["title"]);
$couponBeingCreated->setShortDescription($data["shortDescription"]);
$couponBeingCreated->setDescription($data["description"]);
$couponBeingCreated->setAmount($data["amount"]);
$couponBeingCreated->setIsEnabled($data["isEnabled"]);
$couponBeingCreated->setExpirationDate($data["expirationDate"]);
$couponBeingCreated->setSerializedRules(
new CouponRuleCollection(
array()
)
);
$couponBeingCreated->setIsCumulative($data["isCumulative"]);
$couponBeingCreated->setIsRemovingPostage(
$data["isRemovingPostage"]
);
$couponBeingCreated->setMaxUsage($data["maxUsage"]);
$couponBeingCreated->setIsAvailableOnSpecialOffers(
$data["isAvailableOnSpecialOffers"]
);
return $couponBeingCreated;
}
}

View File

@@ -0,0 +1,81 @@
<?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\Coupon;
use Thelia\Core\Event\ActionEvent;
use Thelia\Model\Coupon;
/**
* Created by JetBrains PhpStorm.
* Date: 8/29/13
* Time: 3:45 PM
*
* Occurring when a Coupon is created
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class CouponCreateEvent extends ActionEvent
{
/**
* @var Coupon Coupon being created
*/
protected $createdCoupon;
/**
* Constructor
*
* @param Coupon $coupon Coupon being created
*/
public function __construct(Coupon $coupon)
{
$this->createdCoupon = $coupon;
}
/**
* Modify Coupon being created
*
* @param Coupon $createdCoupon Coupon being created
*
* @return $this
*/
public function setCreatedCoupon(Coupon $createdCoupon)
{
$this->createdCoupon = $createdCoupon;
return $this;
}
/**
* Get Coupon being created
*
* @return Coupon
*/
public function getCreatedCoupon()
{
return clone $this->createdCoupon;
}
}

View File

@@ -0,0 +1,103 @@
<?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\Coupon;
use Thelia\Model\Coupon;
/**
* Created by JetBrains PhpStorm.
* Date: 8/29/13
* Time: 3:45 PM
*
* Occurring when a Coupon is disabled
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class CouponDisableEvent extends ActionEvent
{
/** @var int Coupon id */
protected $couponId;
/** @var Coupon Coupon being disabled */
protected $disabledCoupon;
/**
* Constructor
*
* @param int $id Coupon Id
*/
public function __construct($id)
{
$this->id = $id;
}
/**
* Get Coupon id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set Coupon id
*
* @param int $id Coupon id
*
* @return $this
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get Coupon being disabled
*
* @return Coupon
*/
public function getDisabledCoupon()
{
return $this->disabledCoupon;
}
/**
* Set Coupon to be disabled
*
* @param Coupon $disabledCoupon Coupon to disable
*
* @return $this
*/
public function setDisabledCoupon(Coupon $disabledCoupon)
{
$this->disabledCoupon = $disabledCoupon;
return $this;
}
}

View File

@@ -0,0 +1,82 @@
<?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\Coupon;
use Thelia\Core\Event\ActionEvent;
use Thelia\Model\Coupon;
/**
* Created by JetBrains PhpStorm.
* Date: 8/29/13
* Time: 3:45 PM
*
* Occurring when a Coupon is edited
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class CouponEditEvent extends ActionEvent
{
/** @var int Coupon being edited id */
protected $couponId;
/** @var Coupon Coupon being created */
protected $editedCoupon;
/**
* Constructor
*
* @param Coupon $coupon Coupon being edited
*/
public function __construct(Coupon $coupon)
{
$this->created_coupon = $coupon;
}
/**
* Modify Coupon being created
*
* @param Coupon $editedCoupon Coupon being created
*
* @return $this
*/
public function setCreatedCoupon(Coupon $editedCoupon)
{
$this->editedCoupon = $editedCoupon;
return $this;
}
/**
* Get Coupon being created
*
* @return Coupon
*/
public function getCreatedCoupon()
{
return clone $this->editedCoupon;
}
}

View File

@@ -0,0 +1,103 @@
<?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\Coupon;
use Thelia\Model\Coupon;
/**
* Created by JetBrains PhpStorm.
* Date: 8/29/13
* Time: 3:45 PM
*
* Occurring when a Coupon is enabled
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class CouponEnableEvent extends ActionEvent
{
/** @var int Coupon id */
protected $couponId;
/** @var Coupon Coupon being enabled */
protected $enabledCoupon;
/**
* Constructor
*
* @param int $id Coupon Id
*/
public function __construct($id)
{
$this->id = $id;
}
/**
* Get Coupon id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set Coupon id
*
* @param int $id Coupon id
*
* @return $this
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get Coupon being enabled
*
* @return Coupon
*/
public function getEnabledCoupon()
{
return $this->enabledCoupon;
}
/**
* Set Coupon to be enabled
*
* @param Coupon $enabledCoupon Coupon to enabled
*
* @return $this
*/
public function setEnabledCoupon(Coupon $enabledCoupon)
{
$this->enabledCoupon = $enabledCoupon;
return $this;
}
}

View File

@@ -177,4 +177,76 @@ final class TheliaEvents
* Sent on cimage cache clear request
*/
const IMAGE_CLEAR_CACHE = "action.clearImageCache";
/**
* Sent when creating a Coupon
*/
const COUPON_CREATE = "action.create_coupon";
/**
* Sent just before a successful insert of a new Coupon in the database.
*/
const BEFORE_CREATE_COUPON = "action.before_create_coupon";
/**
* Sent just after a successful insert of a new Coupon in the database.
*/
const AFTER_CREATE_COUPON = "action.after_create_coupon";
/**
* Sent when editing a Coupon
*/
const COUPON_EDIT = "action.edit_coupon";
/**
* Sent just before a successful update of a new Coupon in the database.
*/
const BEFORE_EDIT_COUPON = "action.before_edit_coupon";
/**
* Sent just after a successful update of a new Coupon in the database.
*/
const AFTER_EDIT_COUPON = "action.after_edit_coupon";
/**
* Sent when disabling a Coupon
*/
const COUPON_DISABLE = "action.disable_coupon";
/**
* Sent just before a successful disable of a new Coupon in the database.
*/
const BEFORE_DISABLE_COUPON = "action.before_disable_coupon";
/**
* Sent just after a successful disable of a new Coupon in the database.
*/
const AFTER_DISABLE_COUPON = "action.after_disable_coupon";
/**
* Sent when enabling a Coupon
*/
const COUPON_ENABLE = "action.enable_coupon";
/**
* Sent just before a successful enable of a new Coupon in the database.
*/
const BEFORE_ENABLE_COUPON = "action.before_enable_coupon";
/**
* Sent just after a successful enable of a new Coupon in the database.
*/
const AFTER_ENABLE_COUPON = "action.after_enable_coupon";
/**
* Sent just before an attempt to use a Coupon
*/
const BEFORE_USE_COUPON = "action.before_use_coupon";
/**
* Sent just after an attempt to use a Coupon
*/
const AFTER_USE_COUPON = "action.after_use_coupon";
}

View File

@@ -28,6 +28,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Thelia\Core\Template\Loop\Argument\Argument;
use Propel\Runtime\ActiveQuery\ModelCriteria;
use Thelia\Core\Security\SecurityContext;
use Thelia\Model\Tools\ModelCriteriaTools;
/**
*
@@ -234,6 +235,28 @@ abstract class BaseLoop
}
}
/**
* Setup ModelCriteria for proper i18n processing
*
* @param ModelCriteria $search the Propel Criteria to configure
* @param array $columns the i18n columns
* @param string $foreignTable the specified table (default to criteria table)
* @param string $foreignKey the foreign key in this table (default to criteria table)
*/
protected function configureI18nProcessing(ModelCriteria $search, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID') {
/* manage translations */
ModelCriteriaTools::getI18n(
$this->getBackend_context(),
$this->getLang(),
$search,
$this->request->getSession()->getLocale(),
$columns,
$foreignTable,
$foreignKey
);
}
/**
*
* this function have to be implement in your own loop class.

View File

@@ -34,7 +34,6 @@ use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Log\Tlog;
use Thelia\Model\Base\LangQuery;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\Model\Base\CategoryQuery;
use Thelia\Model\Base\ProductCategoryQuery;
@@ -92,7 +91,7 @@ class Attribute extends BaseLoop
$lang = $this->getLang();
/* manage translations */
ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale());
$this->configureI18nProcessing($search);
$id = $this->getId();

View File

@@ -33,8 +33,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Log\Tlog;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\Model\Base\AttributeAvQuery;
use Thelia\Model\ConfigQuery;
use Thelia\Type\TypeCollection;
@@ -79,12 +77,8 @@ class AttributeAvailability extends BaseLoop
{
$search = AttributeAvQuery::create();
$backendContext = $this->getBackend_context();
$lang = $this->getLang();
/* manage translations */
ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale());
$this->configureI18nProcessing($search);
$id = $this->getId();

View File

@@ -33,8 +33,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Log\Tlog;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\Model\Base\AttributeCombinationQuery;
use Thelia\Model\Map\AttributeAvTableMap;
use Thelia\Model\Map\AttributeTableMap;
@@ -59,6 +57,7 @@ class AttributeCombination extends BaseLoop
{
return new ArgumentCollection(
Argument::createIntTypeArgument('product_sale_elements', null, true),
Argument::createIntTypeArgument('lang'),
new Argument(
'order',
new TypeCollection(
@@ -79,20 +78,16 @@ class AttributeCombination extends BaseLoop
$search = AttributeCombinationQuery::create();
/* manage attribute translations */
ModelCriteriaTools::getFrontEndI18n(
$this->configureI18nProcessing(
$search,
ConfigQuery::read("default_lang_without_translation", 1),
$this->request->getSession()->getLocale(),
array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'),
AttributeTableMap::TABLE_NAME,
'ATTRIBUTE_ID'
);
/* manage attributeAv translations */
ModelCriteriaTools::getFrontEndI18n(
$this->configureI18nProcessing(
$search,
ConfigQuery::read("default_lang_without_translation", 1),
$this->request->getSession()->getLocale(),
array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'),
AttributeAvTableMap::TABLE_NAME,
'ATTRIBUTE_AV_ID'

View File

@@ -32,8 +32,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Log\Tlog;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\Model\CategoryQuery;
use Thelia\Model\ConfigQuery;
use Thelia\Type\TypeCollection;
@@ -98,12 +96,8 @@ class Category extends BaseLoop
{
$search = CategoryQuery::create();
$backendContext = $this->getBackend_context();
$lang = $this->getLang();
/* manage translations */
ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale());
$this->configureI18nProcessing($search);
$id = $this->getId();
@@ -169,7 +163,6 @@ class Category extends BaseLoop
$loopResult = new LoopResult();
foreach ($categories as $category) {
/*
* no cause pagination lost :
* if ($this->getNotEmpty() && $category->countAllProducts() == 0) continue;

View File

@@ -65,7 +65,8 @@ class CategoryPath extends BaseLoop
Argument::createIntTypeArgument('category', null, true),
Argument::createIntTypeArgument('depth'),
Argument::createIntTypeArgument('level'),
Argument::createBooleanOrBothTypeArgument('visible', true, false)
Argument::createBooleanOrBothTypeArgument('visible', true, false),
Argument::createIntTypeArgument('lang')
);
}
@@ -80,6 +81,9 @@ class CategoryPath extends BaseLoop
$visible = $this->getVisible();
$search = CategoryQuery::create();
$this->configureI18nProcessing($search, array('TITLE'));
$search->filterById($id);
if ($visible != BooleanOrBothType::ANY) $search->filterByVisible($visible);
@@ -95,7 +99,7 @@ class CategoryPath extends BaseLoop
$loopResultRow = new LoopResultRow();
$loopResultRow
->set("TITLE",$category->getTitle())
->set("TITLE",$category->getVirtualColumn('i18n_TITLE'))
->set("URL", $category->getUrl())
->set("ID", $category->getId())
;
@@ -114,8 +118,11 @@ class CategoryPath extends BaseLoop
$ids[] = $parent;
$search = CategoryQuery::create();
$this->configureI18nProcessing($search, array('TITLE'));
$search->filterById($parent);
if ($visible == true) $search->filterByVisible($visible);
if ($visible != BooleanOrBothType::ANY) $search->filterByVisible($visible);
}
}
} while ($category != null && $parent > 0);

View File

@@ -31,8 +31,6 @@ use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\Model\FolderQuery;
use Thelia\Model\Map\ContentTableMap;
use Thelia\Model\ContentFolderQuery;
@@ -88,12 +86,8 @@ class Content extends BaseLoop
{
$search = ContentQuery::create();
$backendContext = $this->getBackend_context();
$lang = $this->getLang();
/* manage translations */
ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale());
$this->configureI18nProcessing($search);
$id = $this->getId();

View File

@@ -31,8 +31,6 @@ use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\Model\CountryQuery;
use Thelia\Model\ConfigQuery;
@@ -70,12 +68,8 @@ class Country extends BaseLoop
{
$search = CountryQuery::create();
$backendContext = $this->getBackend_context();
$lang = $this->getLang();
/* manage translations */
ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale());
$this->configureI18nProcessing($search);
$id = $this->getId();

View File

@@ -31,8 +31,6 @@ use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\Model\CurrencyQuery;
use Thelia\Model\ConfigQuery;
@@ -69,12 +67,8 @@ class Currency extends BaseLoop
{
$search = CurrencyQuery::create();
$backendContext = $this->getBackend_context();
$lang = $this->getLang();
/* manage translations */
ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale(), array('NAME'));
$this->configureI18nProcessing($search, array('NAME'));
$id = $this->getId();

View File

@@ -31,8 +31,6 @@ use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\Model\Base\CategoryQuery;
use Thelia\Model\Base\ProductCategoryQuery;
use Thelia\Model\Base\FeatureQuery;
@@ -84,12 +82,8 @@ class Feature extends BaseLoop
{
$search = FeatureQuery::create();
$backendContext = $this->getBackend_context();
$lang = $this->getLang();
/* manage translations */
ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale());
$this->configureI18nProcessing($search);
$id = $this->getId();

View File

@@ -31,8 +31,6 @@ use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\Model\Base\FeatureAvQuery;
use Thelia\Model\ConfigQuery;
use Thelia\Type\TypeCollection;
@@ -77,12 +75,8 @@ class FeatureAvailability extends BaseLoop
{
$search = FeatureAvQuery::create();
$backendContext = $this->getBackend_context();
$lang = $this->getLang();
/* manage translations */
ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale());
$this->configureI18nProcessing($search);
$id = $this->getId();

View File

@@ -33,8 +33,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Log\Tlog;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\Model\Base\FeatureProductQuery;
use Thelia\Model\ConfigQuery;
use Thelia\Model\Map\FeatureAvTableMap;
@@ -70,7 +68,8 @@ class FeatureValue extends BaseLoop
new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse'))
),
'manual'
)
),
Argument::createIntTypeArgument('lang')
);
}
@@ -84,10 +83,8 @@ class FeatureValue extends BaseLoop
$search = FeatureProductQuery::create();
/* manage featureAv translations */
ModelCriteriaTools::getFrontEndI18n(
$this->configureI18nProcessing(
$search,
ConfigQuery::read("default_lang_without_translation", 1),
$this->request->getSession()->getLocale(),
array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'),
FeatureAvTableMap::TABLE_NAME,
'FEATURE_AV_ID'

View File

@@ -32,8 +32,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Log\Tlog;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\Model\FolderQuery;
use Thelia\Model\ConfigQuery;
use Thelia\Type\TypeCollection;
@@ -80,12 +78,8 @@ class Folder extends BaseLoop
{
$search = FolderQuery::create();
$backendContext = $this->getBackend_context();
$lang = $this->getLang();
/* manage translations */
ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale());
$this->configureI18nProcessing($search);
$id = $this->getId();

View File

@@ -207,16 +207,8 @@ class Image extends BaseLoop
}
/**
* \Criteria::INNER_JOIN in second parameter for joinWithI18n exclude query without translation.
*
* @todo : verify here if we want results for row without translations.
*/
$search->joinWithI18n(
$this->request->getSession()->getLocale(),
(ConfigQuery::read("default_lang_without_translation", 1)) ? Criteria::LEFT_JOIN : Criteria::INNER_JOIN
);
/* manage translations */
$this->configureI18nProcessing($search);
$results = $this->search($search, $pagination);
@@ -295,6 +287,7 @@ class Image extends BaseLoop
),
'manual'
),
Argument::createIntTypeArgument('lang'),
Argument::createIntTypeArgument('width'),
Argument::createIntTypeArgument('height'),

View File

@@ -33,8 +33,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Log\Tlog;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\Model\CategoryQuery;
use Thelia\Model\Map\FeatureProductTableMap;
use Thelia\Model\Map\ProductPriceTableMap;
@@ -138,12 +136,8 @@ class Product extends BaseLoop
{
$search = ProductQuery::create();
$backendContext = $this->getBackend_context();
$lang = $this->getLang();
/* manage translations */
ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale());
$this->configureI18nProcessing($search);
$attributeNonStrictMatch = $this->getAttribute_non_strict_match();
$isPSELeftJoinList = array();

View File

@@ -31,8 +31,6 @@ use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\Model\CustomerTitleQuery;
use Thelia\Model\ConfigQuery;
@@ -67,12 +65,8 @@ class Title extends BaseLoop
{
$search = CustomerTitleQuery::create();
$backendContext = $this->getBackend_context();
$lang = $this->getLang();
/* manage translations */
ModelCriteriaTools::getI18n($backendContext, $lang, $search, ConfigQuery::read("default_lang_without_translation", 1), $this->request->getSession()->getLocale(), array('SHORT', 'LONG'));
$this->configureI18nProcessing($search, array('SHORT', 'LONG'));
$id = $this->getId();

View File

@@ -0,0 +1,168 @@
<?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\NotBlank;
/**
* Created by JetBrains PhpStorm.
* Date: 8/29/13
* Time: 3:45 PM
*
* Allow to build a form Coupon
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class CouponCreationForm extends BaseForm
{
/**
* Build Coupon form
*
* @return void
*/
protected function buildForm()
{
$this->formBuilder
->add(
"code",
"text",
array(
"constraints" => array(
new NotBlank()
)
)
)
->add(
"type",
"text",
array(
"constraints" => array(
new NotBlank()
)
)
)
->add(
"title",
"text",
array(
"constraints" => array(
new NotBlank()
)
)
)
->add(
"shortDescription",
"text",
array(
"constraints" => array(
new NotBlank()
)
)
)
->add(
"description",
"text",
array(
"constraints" => array(
new NotBlank()
)
)
)
->add(
"amount",
"text",
array(
"constraints" => array(
new NotBlank()
)
)
)
->add(
"isEnabled",
"text",
array(
"constraints" => array(
new NotBlank()
)
)
)
->add(
"expirationDate",
"text",
array(
"constraints" => array(
new NotBlank()
)
)
)
->add(
"isCumulative",
"text",
array(
"constraints" => array(
new NotBlank()
)
)
)
->add(
"isRemovingPostage",
"text",
array(
"constraints" => array(
new NotBlank()
)
)
)
->add(
"maxUsage",
"text",
array(
"constraints" => array(
new NotBlank()
)
)
)
->add(
"isAvailableOnSpecialOffers",
"text",
array(
"constraints" => array(
new NotBlank()
)
)
);
}
/**
* Get form name
*
* @return string
*/
public function getName()
{
return "thelia_coupon_creation";
}
}

View File

@@ -48,7 +48,7 @@ class Category extends BaseCategory
->findOne()
;
return $last->getPosition() + 1;
return $last != null ? $last->getPosition() + 1 : 1;
}
/**
@@ -74,6 +74,4 @@ class Category extends BaseCategory
return $countProduct;
}
}
}

View File

@@ -1,9 +1,77 @@
<?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\Model;
use Thelia\Coupon\CouponRuleCollection;
use Thelia\Model\Base\Coupon as BaseCoupon;
class Coupon extends BaseCoupon {
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Used to provide an effect (mostly a discount)
* at the end of the Customer checkout tunnel
* It will be usable for a Customer only if it matches the Coupon criteria (Rules)
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class Coupon extends BaseCoupon
{
/**
* Set the value of [serialized_rules] column.
*
* @param CouponRuleCollection $rules A set of Rules
*
* @return \Thelia\Model\Coupon The current object (for fluent API support)
*/
public function setSerializedRules(CouponRuleCollection $rules)
{
if ($rules !== null) {
$v = (string) base64_encode(serialize($rules));
}
if ($this->serialized_rules !== $v) {
$this->serialized_rules = $v;
$this->modifiedColumns[] = CouponTableMap::SERIALIZED_RULES;
}
return $this;
} // setSerializedRules()
/**
* Get the [serialized_rules] column value.
*
* @return CouponRuleCollection Rules ready to be processed
*/
public function getSerializedRules()
{
return unserialize(base64_decode($this->serialized_rules));
}
}

View File

@@ -6,6 +6,7 @@ use Propel\Runtime\ActiveQuery\Criteria;
use Propel\Runtime\ActiveQuery\Join;
use Propel\Runtime\ActiveQuery\ModelCriteria;
use Thelia\Model\Base\LangQuery;
use Thelia\Model\ConfigQuery;
/**
* Class ModelCriteriaTools
@@ -17,13 +18,12 @@ class ModelCriteriaTools
{
/**
* @param ModelCriteria $search
* @param $defaultLangWithoutTranslation
* @param $askedLocale
* @param $requestedLocale
* @param array $columns
* @param null $foreignTable
* @param string $foreignKey
*/
public static function getFrontEndI18n(ModelCriteria &$search, $defaultLangWithoutTranslation, $askedLocale, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID')
public static function getFrontEndI18n(ModelCriteria &$search, $requestedLocale, $columns, $foreignTable, $foreignKey)
{
if($foreignTable === null) {
$foreignTable = $search->getTableMap()->getName();
@@ -32,21 +32,24 @@ class ModelCriteriaTools
$aliasPrefix = $foreignTable . '_';
}
$askedLocaleI18nAlias = 'asked_locale_i18n';
$defaultLangWithoutTranslation = ConfigQuery::read("default_lang_without_translation", 1);
$requestedLocaleI18nAlias = 'requested_locale_i18n';
$defaultLocaleI18nAlias = 'default_locale_i18n';
if($defaultLangWithoutTranslation == 0) {
$askedLocaleJoin = new Join();
$askedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $askedLocaleI18nAlias);
$askedLocaleJoin->setJoinType(Criteria::INNER_JOIN);
if (!$defaultLangWithoutTranslation == 0) {
$search->addJoinObject($askedLocaleJoin, $askedLocaleI18nAlias)
->addJoinCondition($askedLocaleI18nAlias ,'`' . $askedLocaleI18nAlias . '`.LOCALE = ?', $askedLocale, null, \PDO::PARAM_STR);
$requestedLocaleJoin = new Join();
$requestedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $requestedLocaleI18nAlias);
$requestedLocaleJoin->setJoinType(Criteria::INNER_JOIN);
$search->withColumn('NOT ISNULL(`' . $askedLocaleI18nAlias . '`.`ID`)', $aliasPrefix . 'IS_TRANSLATED');
$search->addJoinObject($requestedLocaleJoin, $requestedLocaleI18nAlias)
->addJoinCondition($requestedLocaleI18nAlias ,'`' . $requestedLocaleI18nAlias . '`.LOCALE = ?', $requestedLocale, null, \PDO::PARAM_STR);
$search->withColumn('NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.`ID`)', $aliasPrefix . 'IS_TRANSLATED');
foreach($columns as $column) {
$search->withColumn('`' . $askedLocaleI18nAlias . '`.`' . $column . '`', $aliasPrefix . 'i18n_' . $column);
$search->withColumn('`' . $requestedLocaleI18nAlias . '`.`' . $column . '`', $aliasPrefix . 'i18n_' . $column);
}
} else {
$defaultLocale = LangQuery::create()->findOneById($defaultLangWithoutTranslation)->getLocale();
@@ -58,24 +61,24 @@ class ModelCriteriaTools
$search->addJoinObject($defaultLocaleJoin, $defaultLocaleI18nAlias)
->addJoinCondition($defaultLocaleI18nAlias ,'`' . $defaultLocaleI18nAlias . '`.LOCALE = ?', $defaultLocale, null, \PDO::PARAM_STR);
$askedLocaleJoin = new Join();
$askedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $askedLocaleI18nAlias);
$askedLocaleJoin->setJoinType(Criteria::LEFT_JOIN);
$requestedLocaleJoin = new Join();
$requestedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $requestedLocaleI18nAlias);
$requestedLocaleJoin->setJoinType(Criteria::LEFT_JOIN);
$search->addJoinObject($askedLocaleJoin, $askedLocaleI18nAlias)
->addJoinCondition($askedLocaleI18nAlias ,'`' . $askedLocaleI18nAlias . '`.LOCALE = ?', $askedLocale, null, \PDO::PARAM_STR);
$search->addJoinObject($requestedLocaleJoin, $requestedLocaleI18nAlias)
->addJoinCondition($requestedLocaleI18nAlias ,'`' . $requestedLocaleI18nAlias . '`.LOCALE = ?', $requestedLocale, null, \PDO::PARAM_STR);
$search->withColumn('NOT ISNULL(`' . $askedLocaleI18nAlias . '`.`ID`)', $aliasPrefix . 'IS_TRANSLATED');
$search->withColumn('NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.`ID`)', $aliasPrefix . 'IS_TRANSLATED');
$search->where('NOT ISNULL(`' . $askedLocaleI18nAlias . '`.ID)')->_or()->where('NOT ISNULL(`' . $defaultLocaleI18nAlias . '`.ID)');
$search->where('NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.ID)')->_or()->where('NOT ISNULL(`' . $defaultLocaleI18nAlias . '`.ID)');
foreach($columns as $column) {
$search->withColumn('CASE WHEN NOT ISNULL(`' . $askedLocaleI18nAlias . '`.ID) THEN `' . $askedLocaleI18nAlias . '`.`' . $column . '` ELSE `' . $defaultLocaleI18nAlias . '`.`' . $column . '` END', $aliasPrefix . 'i18n_' . $column);
$search->withColumn('CASE WHEN NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.ID) THEN `' . $requestedLocaleI18nAlias . '`.`' . $column . '` ELSE `' . $defaultLocaleI18nAlias . '`.`' . $column . '` END', $aliasPrefix . 'i18n_' . $column);
}
}
}
public static function getBackEndI18n(ModelCriteria &$search, $askedLocale, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID')
public static function getBackEndI18n(ModelCriteria &$search, $requestedLocale, $columns, $foreignTable, $foreignKey)
{
if($foreignTable === null) {
$foreignTable = $search->getTableMap()->getName();
@@ -84,35 +87,44 @@ class ModelCriteriaTools
$aliasPrefix = $foreignTable . '_';
}
$askedLocaleI18nAlias = 'asked_locale_i18n';
$requestedLocaleI18nAlias = 'requested_locale_i18n';
$askedLocaleJoin = new Join();
$askedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $askedLocaleI18nAlias);
$askedLocaleJoin->setJoinType(Criteria::LEFT_JOIN);
$requestedLocaleJoin = new Join();
$requestedLocaleJoin->addExplicitCondition($search->getTableMap()->getName(), $foreignKey, null, $foreignTable . '_i18n', 'ID', $requestedLocaleI18nAlias);
$requestedLocaleJoin->setJoinType(Criteria::LEFT_JOIN);
$search->addJoinObject($askedLocaleJoin, $askedLocaleI18nAlias)
->addJoinCondition($askedLocaleI18nAlias ,'`' . $askedLocaleI18nAlias . '`.LOCALE = ?', $askedLocale, null, \PDO::PARAM_STR);
$search->addJoinObject($requestedLocaleJoin, $requestedLocaleI18nAlias)
->addJoinCondition($requestedLocaleI18nAlias ,'`' . $requestedLocaleI18nAlias . '`.LOCALE = ?', $requestedLocale, null, \PDO::PARAM_STR);
$search->withColumn('NOT ISNULL(`' . $askedLocaleI18nAlias . '`.`ID`)', $aliasPrefix . 'IS_TRANSLATED');
$search->withColumn('NOT ISNULL(`' . $requestedLocaleI18nAlias . '`.`ID`)', $aliasPrefix . 'IS_TRANSLATED');
foreach($columns as $column) {
$search->withColumn('`' . $askedLocaleI18nAlias . '`.`' . $column . '`', $aliasPrefix . 'i18n_' . $column);
$search->withColumn('`' . $requestedLocaleI18nAlias . '`.`' . $column . '`', $aliasPrefix . 'i18n_' . $column);
}
}
public static function getI18n($backendContext, $lang, ModelCriteria &$search, $defaultLangWithoutTranslation, $currentLocale, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID')
public static function getI18n($backendContext, $requestedLangId, ModelCriteria &$search, $currentLocale, $columns, $foreignTable, $foreignKey)
{
if($lang !== null) {
$localeSearch = LangQuery::create()->findOneById($lang);
if($localeSearch === null) {
throw new \InvalidArgumentException('Incorrect lang argument given in attribute loop');
// If a lang has been requested, find the related Lang object, and get the locale
if ($requestedLangId !== null) {
$localeSearch = LangQuery::create()->findOneById($requestedLangId);
if ($localeSearch === null) {
throw new \InvalidArgumentException(sprintf('Incorrect lang argument given in attribute loop: lang ID %d not found', $requestedLangId));
}
$locale = $localeSearch->getLocale();
}
else {
// Use the currently defined locale
$locale = $currentLocale;
}
if($backendContext) {
self::getBackEndI18n($search, $lang === null ? $currentLocale : $localeSearch->getLocale(), $columns, $foreignTable, $foreignKey);
// Call the proper method depending on the context: front or back
if ($backendContext) {
self::getBackEndI18n($search, $locale, $columns, $foreignTable, $foreignKey);
} else {
self::getFrontEndI18n($search, $defaultLangWithoutTranslation, $lang === null ? $currentLocale : $localeSearch->getLocale(), $columns, $foreignTable, $foreignKey);
self::getFrontEndI18n($search, $locale, $columns, $foreignTable, $foreignKey);
}
}
}

View File

@@ -0,0 +1,161 @@
<?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\Coupon;
use InvalidArgumentException;
use Thelia\Constraint\Validator\CustomerParam;
use Thelia\Constraint\Validator\PriceParam;
use Thelia\Constraint\Validator\QuantityParam;
use Thelia\Model\Customer;
/**
* Created by JetBrains PhpStorm.
* Date: 8/19/13
* Time: 3:24 PM
*
* Unit Test CustomerParam Class
*
* @package Constraint
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class CustomerParamTest extends \PHPUnit_Framework_TestCase
{
/** @var CouponAdapterInterface $stubTheliaAdapter */
protected $stubTheliaAdapter = null;
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
/** @var CouponAdapterInterface $stubTheliaAdapter */
$this->stubTheliaAdapter = $this->generateValidCouponBaseAdapterMock();
}
/**
* Generate valid CouponBaseAdapter
*
* @param int $customerId Customer id
*
* @return CouponAdapterInterface
*/
protected function generateValidCouponBaseAdapterMock($customerId = 4521)
{
$customer = new Customer();
$customer->setId($customerId);
$customer->setFirstname('Firstname');
$customer->setLastname('Lastname');
$customer->setEmail('em@il.com');
/** @var CouponAdapterInterface $stubTheliaAdapter */
$stubTheliaAdapter = $this->getMock(
'Thelia\Coupon\CouponBaseAdapter',
array('getCustomer'),
array()
);
$stubTheliaAdapter->expects($this->any())
->method('getCustomer')
->will($this->returnValue($customer));
return $stubTheliaAdapter;
}
/**
*
* @covers Thelia\Coupon\Parameter\QuantityParam::compareTo
*
*/
public function testCanUseCoupon()
{
$customerId = 4521;
$couponValidForCustomerId = 4521;
$adapter = $this->generateValidCouponBaseAdapterMock($customerId);
$customerParam = new CustomerParam($adapter, $couponValidForCustomerId);
$expected = 0;
$actual = $customerParam->compareTo($customerId);
$this->assertEquals($expected, $actual);
}
// /**
// *
// * @covers Thelia\Coupon\Parameter\QuantityParam::compareTo
// *
// */
// public function testCanNotUseCouponTest()
// {
//
// }
//
// /**
// *
// * @covers Thelia\Coupon\Parameter\QuantityParam::compareTo
// * @expectedException InvalidArgumentException
// *
// */
// public function testCanNotUseCouponCustomerNotFoundTest()
// {
//
// }
// /**
// * Test is the object is serializable
// * If no data is lost during the process
// */
// public function isSerializableTest()
// {
// $adapter = new CouponBaseAdapter();
// $intValidator = 42;
// $intToValidate = -1;
//
// $param = new QuantityParam($adapter, $intValidator);
//
// $serialized = base64_encode(serialize($param));
// /** @var QuantityParam $unserialized */
// $unserialized = base64_decode(serialize($serialized));
//
// $this->assertEquals($param->getValue(), $unserialized->getValue());
// $this->assertEquals($param->getInteger(), $unserialized->getInteger());
//
// $new = new QuantityParam($adapter, $unserialized->getInteger());
// $this->assertEquals($param->getInteger(), $new->getInteger());
// }
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
}

View File

@@ -1,2 +0,0 @@
# Sqlfile -> Database map
thelia.sql=thelia

View File

@@ -1,4 +1,4 @@
/*! X-editable - v1.4.6
/*! X-editable - v1.4.6
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
@@ -18,45 +18,45 @@
vertical-align: top;
margin-left: 7px;
/* inline-block emulation for IE7*/
zoom: 1;
zoom: 1;
*display: inline;
}
.editable-buttons.editable-buttons-bottom {
display: block;
display: block;
margin-top: 7px;
margin-left: 0;
}
.editable-input {
vertical-align: top;
vertical-align: top;
display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
width: auto; /* bootstrap-responsive has width: 100% that breakes layout */
white-space: normal; /* reset white-space decalred in parent*/
/* display-inline emulation for IE7*/
zoom: 1;
*display: inline;
zoom: 1;
*display: inline;
}
.editable-buttons .editable-cancel {
margin-left: 7px;
margin-left: 7px;
}
/*for jquery-ui buttons need set height to look more pretty*/
.editable-buttons button.ui-button-icon-only {
height: 24px;
height: 24px;
width: 30px;
}
.editableform-loading {
background: url('../img/loading.gif') center center no-repeat;
background: url('../img/loading.gif') center center no-repeat;
height: 25px;
width: auto;
min-width: 25px;
width: auto;
min-width: 25px;
}
.editable-inline .editableform-loading {
background-position: left 5px;
background-position: left 5px;
}
.editable-error-block {
@@ -68,17 +68,17 @@
/*add padding for jquery ui*/
.editable-error-block.ui-state-error {
padding: 3px;
}
padding: 3px;
}
.editable-error {
color: red;
color: red;
}
/* ---- For specific types ---- */
.editableform .editable-date {
padding: 0;
padding: 0;
margin: 0;
float: left;
}
@@ -86,25 +86,25 @@
/* move datepicker icon to center of add-on button. See https://github.com/vitalets/x-editable/issues/183 */
.editable-inline .add-on .icon-th {
margin-top: 3px;
margin-left: 1px;
margin-left: 1px;
}
/* checklist vertical alignment */
.editable-checklist label input[type="checkbox"],
.editable-checklist label input[type="checkbox"],
.editable-checklist label span {
vertical-align: middle;
margin: 0;
}
.editable-checklist label {
white-space: nowrap;
white-space: nowrap;
}
/* set exact width of textarea to fit buttons toolbar */
.editable-wysihtml5 {
width: 566px;
height: 250px;
width: 566px;
height: 250px;
}
/* clear button shown as link in date inputs */
@@ -119,16 +119,16 @@
.editable-clear-x {
background: url('../img/clear.png') center center no-repeat;
display: block;
width: 13px;
width: 13px;
height: 13px;
position: absolute;
opacity: 0.6;
z-index: 100;
top: 50%;
right: 6px;
margin-top: -6px;
}
.editable-clear-x:hover {
@@ -140,49 +140,49 @@
}
.editable-container.editable-popup {
max-width: none !important; /* without this rule poshytip/tooltip does not stretch */
}
}
.editable-container.popover {
width: auto; /* without this rule popover does not stretch */
}
.editable-container.editable-inline {
display: inline-block;
display: inline-block;
vertical-align: middle;
width: auto;
/* inline-block emulation for IE7*/
zoom: 1;
*display: inline;
zoom: 1;
*display: inline;
}
.editable-container.ui-widget {
font-size: inherit; /* jqueryui widget font 1.1em too big, overwrite it */
z-index: 9990; /* should be less than select2 dropdown z-index to close dropdown first when click */
}
.editable-click,
a.editable-click,
.editable-click,
a.editable-click,
a.editable-click:hover {
text-decoration: none;
border-bottom: dashed 1px #0088cc;
border-bottom: dotted 1px #0088cc;
}
.editable-click.editable-disabled,
a.editable-click.editable-disabled,
.editable-click.editable-disabled,
a.editable-click.editable-disabled,
a.editable-click.editable-disabled:hover {
color: #585858;
color: #585858;
cursor: default;
border-bottom: none;
}
.editable-empty, .editable-empty:hover, .editable-empty:focus{
font-style: italic;
color: #DD1144;
font-style: italic;
color: #DD1144;
/* border-bottom: none; */
text-decoration: none;
}
.editable-unsaved {
font-weight: bold;
font-weight: bold;
}
.editable-unsaved:after {
@@ -194,12 +194,463 @@ a.editable-click.editable-disabled:hover {
-moz-transition: background-color 1400ms ease-out;
-o-transition: background-color 1400ms ease-out;
-ms-transition: background-color 1400ms ease-out;
transition: background-color 1400ms ease-out;
transition: background-color 1400ms ease-out;
}
/*see https://github.com/vitalets/x-editable/issues/139 */
.form-horizontal .editable
{
{
padding-top: 5px;
display:inline-block;
}
}
/*!
* Datepicker for Bootstrap
*
* Copyright 2012 Stefan Petre
* Improvements by Andrew Rowls
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
*/
.datepicker {
padding: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
direction: ltr;
/*.dow {
border-top: 1px solid #ddd !important;
}*/
}
.datepicker-inline {
width: 220px;
}
.datepicker.datepicker-rtl {
direction: rtl;
}
.datepicker.datepicker-rtl table tr td span {
float: right;
}
.datepicker-dropdown {
top: 0;
left: 0;
}
.datepicker-dropdown:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
top: -7px;
left: 6px;
}
.datepicker-dropdown:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #ffffff;
position: absolute;
top: -6px;
left: 7px;
}
.datepicker > div {
display: none;
}
.datepicker.days div.datepicker-days {
display: block;
}
.datepicker.months div.datepicker-months {
display: block;
}
.datepicker.years div.datepicker-years {
display: block;
}
.datepicker table {
margin: 0;
}
.datepicker td,
.datepicker th {
text-align: center;
width: 20px;
height: 20px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: none;
}
.table-striped .datepicker table tr td,
.table-striped .datepicker table tr th {
background-color: transparent;
}
.datepicker table tr td.day:hover {
background: #eeeeee;
cursor: pointer;
}
.datepicker table tr td.old,
.datepicker table tr td.new {
color: #999999;
}
.datepicker table tr td.disabled,
.datepicker table tr td.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td.today,
.datepicker table tr td.today:hover,
.datepicker table tr td.today.disabled,
.datepicker table tr td.today.disabled:hover {
background-color: #fde19a;
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
background-image: linear-gradient(top, #fdd49a, #fdf59a);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
border-color: #fdf59a #fdf59a #fbed50;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #000;
}
.datepicker table tr td.today:hover,
.datepicker table tr td.today:hover:hover,
.datepicker table tr td.today.disabled:hover,
.datepicker table tr td.today.disabled:hover:hover,
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active,
.datepicker table tr td.today.disabled,
.datepicker table tr td.today:hover.disabled,
.datepicker table tr td.today.disabled.disabled,
.datepicker table tr td.today.disabled:hover.disabled,
.datepicker table tr td.today[disabled],
.datepicker table tr td.today:hover[disabled],
.datepicker table tr td.today.disabled[disabled],
.datepicker table tr td.today.disabled:hover[disabled] {
background-color: #fdf59a;
}
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active {
background-color: #fbf069 \9;
}
.datepicker table tr td.today:hover:hover {
color: #000;
}
.datepicker table tr td.today.active:hover {
color: #fff;
}
.datepicker table tr td.range,
.datepicker table tr td.range:hover,
.datepicker table tr td.range.disabled,
.datepicker table tr td.range.disabled:hover {
background: #eeeeee;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.datepicker table tr td.range.today,
.datepicker table tr td.range.today:hover,
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today.disabled:hover {
background-color: #f3d17a;
background-image: -moz-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -o-linear-gradient(top, #f3c17a, #f3e97a);
background-image: linear-gradient(top, #f3c17a, #f3e97a);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
border-color: #f3e97a #f3e97a #edde34;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.datepicker table tr td.range.today:hover,
.datepicker table tr td.range.today:hover:hover,
.datepicker table tr td.range.today.disabled:hover,
.datepicker table tr td.range.today.disabled:hover:hover,
.datepicker table tr td.range.today:active,
.datepicker table tr td.range.today:hover:active,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.active,
.datepicker table tr td.range.today:hover.active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today.disabled:hover.active,
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today:hover.disabled,
.datepicker table tr td.range.today.disabled.disabled,
.datepicker table tr td.range.today.disabled:hover.disabled,
.datepicker table tr td.range.today[disabled],
.datepicker table tr td.range.today:hover[disabled],
.datepicker table tr td.range.today.disabled[disabled],
.datepicker table tr td.range.today.disabled:hover[disabled] {
background-color: #f3e97a;
}
.datepicker table tr td.range.today:active,
.datepicker table tr td.range.today:hover:active,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.active,
.datepicker table tr td.range.today:hover.active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today.disabled:hover.active {
background-color: #efe24b \9;
}
.datepicker table tr td.selected,
.datepicker table tr td.selected:hover,
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected.disabled:hover {
background-color: #9e9e9e;
background-image: -moz-linear-gradient(top, #b3b3b3, #808080);
background-image: -ms-linear-gradient(top, #b3b3b3, #808080);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));
background-image: -webkit-linear-gradient(top, #b3b3b3, #808080);
background-image: -o-linear-gradient(top, #b3b3b3, #808080);
background-image: linear-gradient(top, #b3b3b3, #808080);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);
border-color: #808080 #808080 #595959;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.selected:hover,
.datepicker table tr td.selected:hover:hover,
.datepicker table tr td.selected.disabled:hover,
.datepicker table tr td.selected.disabled:hover:hover,
.datepicker table tr td.selected:active,
.datepicker table tr td.selected:hover:active,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.active,
.datepicker table tr td.selected:hover.active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected.disabled:hover.active,
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected:hover.disabled,
.datepicker table tr td.selected.disabled.disabled,
.datepicker table tr td.selected.disabled:hover.disabled,
.datepicker table tr td.selected[disabled],
.datepicker table tr td.selected:hover[disabled],
.datepicker table tr td.selected.disabled[disabled],
.datepicker table tr td.selected.disabled:hover[disabled] {
background-color: #808080;
}
.datepicker table tr td.selected:active,
.datepicker table tr td.selected:hover:active,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.active,
.datepicker table tr td.selected:hover.active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected.disabled:hover.active {
background-color: #666666 \9;
}
.datepicker table tr td.active,
.datepicker table tr td.active:hover,
.datepicker table tr td.active.disabled,
.datepicker table tr td.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(top, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.active:hover,
.datepicker table tr td.active:hover:hover,
.datepicker table tr td.active.disabled:hover,
.datepicker table tr td.active.disabled:hover:hover,
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active,
.datepicker table tr td.active.disabled,
.datepicker table tr td.active:hover.disabled,
.datepicker table tr td.active.disabled.disabled,
.datepicker table tr td.active.disabled:hover.disabled,
.datepicker table tr td.active[disabled],
.datepicker table tr td.active:hover[disabled],
.datepicker table tr td.active.disabled[disabled],
.datepicker table tr td.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active {
background-color: #003399 \9;
}
.datepicker table tr td span {
display: block;
width: 23%;
height: 54px;
line-height: 54px;
float: left;
margin: 1%;
cursor: pointer;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.datepicker table tr td span:hover {
background: #eeeeee;
}
.datepicker table tr td span.disabled,
.datepicker table tr td span.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td span.active,
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(top, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active:hover:hover,
.datepicker table tr td span.active.disabled:hover,
.datepicker table tr td span.active.disabled:hover:hover,
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active,
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active:hover.disabled,
.datepicker table tr td span.active.disabled.disabled,
.datepicker table tr td span.active.disabled:hover.disabled,
.datepicker table tr td span.active[disabled],
.datepicker table tr td span.active:hover[disabled],
.datepicker table tr td span.active.disabled[disabled],
.datepicker table tr td span.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active {
background-color: #003399 \9;
}
.datepicker table tr td span.old,
.datepicker table tr td span.new {
color: #999999;
}
.datepicker th.datepicker-switch {
width: 145px;
}
.datepicker thead tr:first-child th,
.datepicker tfoot tr th {
cursor: pointer;
}
.datepicker thead tr:first-child th:hover,
.datepicker tfoot tr th:hover {
background: #eeeeee;
}
.datepicker .cw {
font-size: 10px;
width: 12px;
padding: 0 2px 0 5px;
vertical-align: middle;
}
.datepicker thead tr:first-child th.cw {
cursor: default;
background-color: transparent;
}
.input-append.date .add-on i,
.input-prepend.date .add-on i {
display: block;
cursor: pointer;
width: 16px;
height: 16px;
}
.input-daterange input {
text-align: center;
}
.input-daterange input:first-child {
-webkit-border-radius: 3px 0 0 3px;
-moz-border-radius: 3px 0 0 3px;
border-radius: 3px 0 0 3px;
}
.input-daterange input:last-child {
-webkit-border-radius: 0 3px 3px 0;
-moz-border-radius: 0 3px 3px 0;
border-radius: 0 3px 3px 0;
}
.input-daterange .add-on {
display: inline-block;
width: auto;
min-width: 16px;
height: 18px;
padding: 4px 5px;
font-weight: normal;
line-height: 18px;
text-align: center;
text-shadow: 0 1px 0 #ffffff;
vertical-align: middle;
background-color: #eeeeee;
border: 1px solid #ccc;
margin-left: -5px;
margin-right: -5px;
}

View File

@@ -1,31 +1,31 @@
// -- Tools --------------------------------------------------------------------
.rounded(@radius: 2px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
.border-radius(@topright: 0, @bottomright: 0, @bottomleft: 0, @topleft: 0) {
-webkit-border-top-right-radius: @topright;
-webkit-border-bottom-right-radius: @bottomright;
-webkit-border-bottom-left-radius: @bottomleft;
-webkit-border-top-left-radius: @topleft;
-moz-border-radius-topright: @topright;
-moz-border-radius-bottomright: @bottomright;
-moz-border-radius-bottomleft: @bottomleft;
-moz-border-radius-topleft: @topleft;
border-top-right-radius: @topright;
border-bottom-right-radius: @bottomright;
border-bottom-left-radius: @bottomleft;
border-top-left-radius: @topleft;
.background-clip(padding-box);
-webkit-border-top-right-radius: @topright;
-webkit-border-bottom-right-radius: @bottomright;
-webkit-border-bottom-left-radius: @bottomleft;
-webkit-border-top-left-radius: @topleft;
-moz-border-radius-topright: @topright;
-moz-border-radius-bottomright: @bottomright;
-moz-border-radius-bottomleft: @bottomleft;
-moz-border-radius-topleft: @topleft;
border-top-right-radius: @topright;
border-bottom-right-radius: @bottomright;
border-bottom-left-radius: @bottomleft;
border-top-left-radius: @topleft;
.background-clip(padding-box);
}
.background-clip(@argument: padding-box) {
-moz-background-clip: @argument;
-webkit-background-clip: @argument;
background-clip: @argument;
-moz-background-clip: @argument;
-webkit-background-clip: @argument;
background-clip: @argument;
}
.box-shadow(@shadow: 0 1px 2px rgba(0,0,0,.05)) {
@@ -158,13 +158,41 @@ hr {
}
.btn-primary, .btn-large {
<<<<<<< HEAD
#gradient > .vertical(rgb(243,153,34), rgb(227,83,11));
=======
background: #e9730f;
background-image: linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%);
background-image: -o-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%);
background-image: -moz-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%);
background-image: -webkit-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%);
background-image: -ms-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%);
background-image: -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0, rgb(227,83,11)),
color-stop(1, rgb(243,153,34))
);
>>>>>>> 180302e7cce643db7cda695b5cfaec3586ebb72c
box-shadow: inset 0px 0px 2px rgba(250,250,250,0.5), 0px 1px 3px rgba(0,0,0,0.2);
color: white;
}
.btn-large:hover, .btn-primary:hover {
#gradient > .vertical(rgb(243,153,34), rgb(227,83,11));
background: #e9730f;
background-image: linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%);
background-image: -o-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%);
background-image: -moz-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%);
background-image: -webkit-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%);
background-image: -ms-linear-gradient(bottom, rgb(227,83,11) 0%, rgb(243,153,34) 100%);
background-image: -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0, rgb(227,83,11)),
color-stop(1, rgb(243,153,34))
);
box-shadow: inset 0px 0px 2px rgba(250,250,250,0.8), 0px 1px 3px rgba(0,0,0,0.2);
color: white;
}
@@ -762,6 +790,7 @@ label {
// Center the alert box (20px bottom margin) in the table cell
padding: 20px 20px 0 20px;
}
<<<<<<< HEAD
}
// -- Editable tweaks ---------------------------------------------------------
@@ -889,3 +918,6 @@ label {
}
=======
}
>>>>>>> 180302e7cce643db7cda695b5cfaec3586ebb72c

View File

@@ -12,11 +12,11 @@
{if $action == 'edit'}
{intl l='Editing %cat' cat="{$TITLE}"}
{else}
{$TITLE} <a href="{url path="admin/catalog/category/edit/$ID"}" title="{intl l='Edit this category'}">{intl l="(edit)"}</a>
{$TITLE} <a href="{url path='admin/catalog/category' id="$ID" action='edit'}" title="{intl l='Edit this category'}">{intl l="(edit)"}</a>
{/if}
</li>
{else}
<li><a href="{url path="admin/catalog/category/browse/$ID"}">{$TITLE}</a> <span class="divider">/</span></li>
<li><a href="{url path='admin/catalog/category' id="$ID" action='browse'}">{$TITLE}</a> <span class="divider">/</span></li>
{/if}
{/loop}
{/ifloop}

View File

@@ -12,7 +12,7 @@
<ul class="nav nav-pills">
{loop name="lang_list" type="lang" default_only={$default_only}}
<li {if $IS_DEFAULT}class="active"{/if}>
<a href="#" title="{intl l="Edit information for %lng" lng=$TITLE}">
<a href="#" title="{intl l="Edit information in %lng" lng=$TITLE}">
<img src="{image file="../assets/img/flags/{$CODE}.gif"}" alt="{intl l=$TITLE}" />
</a>
</li>