From 8f5a17288bd2a77d32b7348fdd15a0d051862278 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Tue, 29 Apr 2014 15:01:18 +0200 Subject: [PATCH 01/48] Fixed potiential javascript error --- templates/backOffice/default/ajax/product-related-tab.html | 4 ++-- templates/backOffice/default/category-edit.html | 2 +- templates/backOffice/default/content-edit.html | 5 +---- templates/backOffice/default/folder-edit.html | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/templates/backOffice/default/ajax/product-related-tab.html b/templates/backOffice/default/ajax/product-related-tab.html index 1d3efb78e..89b7b554d 100644 --- a/templates/backOffice/default/ajax/product-related-tab.html +++ b/templates/backOffice/default/ajax/product-related-tab.html @@ -560,12 +560,12 @@ $(function() { } }); - // Initialize folder (id={$folder_id}) select value + // Initialize folder select value {if $folder_id != 0} $('#folder_id').val("{$folder_id}").change(); {/if} - // Initialize accessory category id (id={$accessory_category_id}) select value + // Initialize accessory category id select value {if $accessory_category_id != 0} $('#accessory_category_id').val("{$accessory_category_id}").change(); {/if} diff --git a/templates/backOffice/default/category-edit.html b/templates/backOffice/default/category-edit.html index b245ecc04..af50e6c14 100644 --- a/templates/backOffice/default/category-edit.html +++ b/templates/backOffice/default/category-edit.html @@ -380,7 +380,7 @@ $(function() { } }); - // Initialize folder (id={$folder_id}) select value + // Initialize folder select value {if $folder_id != 0} $('#folder_id').val("{$folder_id}").change(); {/if} diff --git a/templates/backOffice/default/content-edit.html b/templates/backOffice/default/content-edit.html index c30dac683..f7e7477aa 100644 --- a/templates/backOffice/default/content-edit.html +++ b/templates/backOffice/default/content-edit.html @@ -266,10 +266,7 @@ form_content = {$smarty.capture.delete_folder_dialog nofilter} }); }); - // Initialize folder (id= - {$folder_id}) - select - value + // Initialize folder select value {if $folder_id != 0} $('#folder_id').val("{$folder_id}").change(); {/if} diff --git a/templates/backOffice/default/folder-edit.html b/templates/backOffice/default/folder-edit.html index 2a22d3741..d5b58625b 100644 --- a/templates/backOffice/default/folder-edit.html +++ b/templates/backOffice/default/folder-edit.html @@ -226,7 +226,7 @@ }); }); - // Initialize folder (id={$folder_id}) select value + // Initialize folder select value {if $folder_id != 0} $('#folder_id').val("{$folder_id}").change(); {/if} From a23116ca615fb1570d7685048f48885e6e61e1e0 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Tue, 29 Apr 2014 19:07:06 +0200 Subject: [PATCH 02/48] Removed check of admin.image/document, whis is not managed in the back-office --- templates/backOffice/default/document-edit.html | 1 - templates/backOffice/default/image-edit.html | 1 - 2 files changed, 2 deletions(-) diff --git a/templates/backOffice/default/document-edit.html b/templates/backOffice/default/document-edit.html index 06d055757..b39cf1aee 100644 --- a/templates/backOffice/default/document-edit.html +++ b/templates/backOffice/default/document-edit.html @@ -2,7 +2,6 @@ {block name="page-title"}{intl l='Edit a document'}{/block} -{block name="check-resource"}admin.document{/block} {block name="check-access"}update{/block} {block name="main-content"} diff --git a/templates/backOffice/default/image-edit.html b/templates/backOffice/default/image-edit.html index bb6bbf7f3..88c7cc5a1 100644 --- a/templates/backOffice/default/image-edit.html +++ b/templates/backOffice/default/image-edit.html @@ -2,7 +2,6 @@ {block name="page-title"}{intl l='Edit an image'}{/block} -{block name="check-resource"}admin.image{/block} {block name="check-access"}update{/block} {block name="main-content"} From 4bcc2f7fa8822fc6776311c5654095e26e60c05f Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Thu, 1 May 2014 19:20:00 +0200 Subject: [PATCH 03/48] Added order parameter, improved request --- core/lib/Thelia/Core/Template/Loop/Coupon.php | 92 +++++++++++++++++-- 1 file changed, 84 insertions(+), 8 deletions(-) diff --git a/core/lib/Thelia/Core/Template/Loop/Coupon.php b/core/lib/Thelia/Core/Template/Loop/Coupon.php index d69d449e5..6885463eb 100644 --- a/core/lib/Thelia/Core/Template/Loop/Coupon.php +++ b/core/lib/Thelia/Core/Template/Loop/Coupon.php @@ -25,6 +25,9 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Coupon\Type\CouponInterface; use Thelia\Model\Coupon as MCoupon; use Thelia\Model\CouponQuery; +use Thelia\Model\Map\CouponTableMap; +use Thelia\Type\EnumListType; +use Thelia\Type\TypeCollection; /** * Coupon Loop @@ -44,7 +47,23 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface { return new ArgumentCollection( Argument::createIntListTypeArgument('id'), - Argument::createBooleanOrBothTypeArgument('is_enabled') + Argument::createBooleanOrBothTypeArgument('is_enabled'), + new Argument( + 'order', + new TypeCollection( + new EnumListType(array( + 'id', 'id-reverse', + 'code', 'code-reverse', + 'title', 'title-reverse', + 'enabled', 'enabled-reverse', + 'expiration-date', 'expiration-date-reverse', + 'days-left', 'days-left-reverse', + 'usages-left', 'usages-left-reverse' + ) + ) + ), + 'code' + ) ); } @@ -66,6 +85,63 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface $search->filterByIsEnabled($isEnabled ? true : false); } + $search->addAsColumn('days_left', 'DATEDIFF('.CouponTableMap::EXPIRATION_DATE.', CURDATE()) - 1'); + + $orders = $this->getOrder(); + + foreach ($orders as $order) { + switch ($order) { + case 'id': + $search->orderById(Criteria::ASC); + break; + case 'id-reverse': + $search->orderById(Criteria::DESC); + break; + + case 'code': + $search->orderByCode(Criteria::ASC); + break; + case 'code-reverse': + $search->orderByCode(Criteria::DESC); + break; + + case 'title': + $search->addAscendingOrderByColumn('i18n_TITLE'); + break; + case 'title-reverse': + $search->addDescendingOrderByColumn('i18n_TITLE'); + break; + + case 'enabled': + $search->orderByIsEnabled(Criteria::ASC); + break; + case 'enabled-reverse': + $search->orderByIsEnabled(Criteria::DESC); + break; + + case 'expiration-date': + $search->orderByExpirationDate(Criteria::ASC); + break; + case 'expiration-date-reverse': + $search->orderByExpirationDate(Criteria::DESC); + break; + + case 'usages-left': + $search->orderByMaxUsage(Criteria::ASC); + break; + case 'usages-left-reverse': + $search->orderByMaxUsage(Criteria::DESC); + break; + + case 'days-left': + $search->addAscendingOrderByColumn('days_left'); + break; + case 'days-left-reverse': + $search->addDescendingOrderByColumn('days_left'); + break; + } + } + return $search; } @@ -81,7 +157,9 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface /** @var MCoupon $coupon */ foreach ($loopResult->getResultDataCollection() as $coupon) { + $loopResultRow = new LoopResultRow($coupon); + $conditions = $conditionFactory->unserializeConditionCollection( $coupon->getSerializedConditions() ); @@ -103,10 +181,6 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface $coupon->getExpirationDate() ); - $now = time(); - $datediff = $coupon->getExpirationDate()->getTimestamp() - $now; - $daysLeftBeforeExpiration = floor($datediff/(60*60*24)); - $cleanedConditions = array(); /** @var ConditionInterface $condition */ foreach ($conditions as $condition) { @@ -116,14 +190,16 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface ); $cleanedConditions[] = $temp; } - $loopResultRow->set("ID", $coupon->getId()) + + $loopResultRow + ->set("ID", $coupon->getId()) ->set("IS_TRANSLATED", $coupon->getVirtualColumn('IS_TRANSLATED')) ->set("LOCALE", $this->locale) ->set("CODE", $coupon->getCode()) ->set("TITLE", $coupon->getVirtualColumn('i18n_TITLE')) ->set("SHORT_DESCRIPTION", $coupon->getVirtualColumn('i18n_SHORT_DESCRIPTION')) ->set("DESCRIPTION", $coupon->getVirtualColumn('i18n_DESCRIPTION')) - ->set("EXPIRATION_DATE", $coupon->getExpirationDate($lang->getDateFormat())) + ->set("EXPIRATION_DATE", $coupon->getExpirationDate()) ->set("USAGE_LEFT", $coupon->getMaxUsage()) ->set("IS_CUMULATIVE", $coupon->getIsCumulative()) ->set("IS_REMOVING_POSTAGE", $coupon->getIsRemovingPostage()) @@ -132,7 +208,7 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface ->set("AMOUNT", $coupon->getAmount()) ->set("APPLICATION_CONDITIONS", $cleanedConditions) ->set("TOOLTIP", $couponManager->getToolTip()) - ->set("DAY_LEFT_BEFORE_EXPIRATION", $daysLeftBeforeExpiration) + ->set("DAY_LEFT_BEFORE_EXPIRATION", max(0, $coupon->getVirtualColumn('days_left'))) ->set("SERVICE_ID", $couponManager->getServiceId()); $loopResult->addRow($loopResultRow); } From 84966858149bc12afcd8bb96540a0feab1954d7b Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Thu, 1 May 2014 19:20:32 +0200 Subject: [PATCH 04/48] Normalized coupon list appearance, added sorting --- .../Controller/Admin/CouponController.php | 3 +- templates/backOffice/default/coupon-list.html | 203 ++++++++++-------- 2 files changed, 117 insertions(+), 89 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/CouponController.php b/core/lib/Thelia/Controller/Admin/CouponController.php index 2f2ad63db..82c3a97d5 100644 --- a/core/lib/Thelia/Controller/Admin/CouponController.php +++ b/core/lib/Thelia/Controller/Admin/CouponController.php @@ -73,6 +73,8 @@ class CouponController extends BaseAdminController Router::ABSOLUTE_URL ); + $args['coupon_order'] = $this->getListOrderFromSession('coupon', 'coupon_order', 'code'); + return $this->render('coupon-list', $args); } @@ -856,5 +858,4 @@ class CouponController extends BaseAdminController ) ); } - } diff --git a/templates/backOffice/default/coupon-list.html b/templates/backOffice/default/coupon-list.html index 4ba344601..30a3327b7 100644 --- a/templates/backOffice/default/coupon-list.html +++ b/templates/backOffice/default/coupon-list.html @@ -14,22 +14,25 @@ + {module_include location='coupon_top'} +
+ - - - - - - - - - {loop type="coupon" name="list_coupon" is_enabled="1" backend_context="true"} - - - - - - - - {/loop} - -
- {intl l='Enabled coupons'} + {intl l='Coupons'} {module_include location='coupon_list_caption'} {loop type="auth" name="can_create" role="ADMIN" resource="admin.coupon" access="CREATE"} - + {/loop} @@ -37,98 +40,119 @@
{block name="coupon-label-code"}{intl l='Code'}{/block}{block name="coupon-label-title"}{intl l='Title'}{/block}{block name="coupon-label-expiration-date"}{intl l='Days before expiration'}{/block}{block name="coupon-label-usage-left"}{intl l='Usage left'}{/block}{block name="coupon-label-action"}{/block}
{block name="coupon-code"}{$CODE}{/block}{block name="coupon-title"}{$TITLE}{/block}{block name="coupon-expiration-date"}{$DAY_LEFT_BEFORE_EXPIRATION}{/block} - {block name="coupon-usage-left"} - {if $USAGE_LEFT == -1} - - {intl l="Unlimited"} - - {elseif $USAGE_LEFT} - - {$USAGE_LEFT} - - {else} - - 0 - - {/if} - {/block} - - {block name="coupon-action"} - - {intl l='Edit'} - - {/block} -
-
-
-
-
+ {admin_sortable_header + current_order=$coupon_order + order='code' + reverse_order='code-reverse' + path={url path='/admin/coupon'} + request_parameter_name='coupon_order' + label="{intl l='Code'}" + } + -
-
-
-
- - - - - - - - - + + + + + + + + + + + {module_include location='coupon_table_header'} + + - {loop type="coupon" name="list_coupon" is_enabled="0" backend_context="true"} + {loop type="coupon" name="list_coupon" order={$coupon_order|default:'code'} backend_context="true"} - - - - + + + + + + + + + + {module_include location='coupon_table_row'} + + {/loop} @@ -136,6 +160,9 @@
- {intl l='Disabled coupons'} -
{block name="coupon-label-code"}{intl l='Code'}{/block}{block name="coupon-label-title"}{intl l='Title'}{/block}{block name="coupon-label-expiration-date"}{intl l='Expiration date'}{/block}{block name="coupon-label-usage-left"}{intl l='Usage left'}{/block}{block name="coupon-label-action"}{/block}{admin_sortable_header + current_order=$coupon_order + order='title' + reverse_order='title-reverse' + path={url path='/admin/coupon'} + request_parameter_name='coupon_order' + label="{intl l='Title'}" + } + {admin_sortable_header + current_order=$coupon_order + order='enabled' + reverse_order='enabled-reverse' + path={url path='/admin/coupon'} + request_parameter_name='coupon_order' + label="{intl l='Status'}" + } + {admin_sortable_header + current_order=$coupon_order + order='expiration-date' + reverse_order='expiration-date-reverse' + path={url path='/admin/coupon'} + request_parameter_name='coupon_order' + label="{intl l='Expiration date'}" + } + {admin_sortable_header + current_order=$coupon_order + order='days-left' + reverse_order='days-left-reverse' + path={url path='/admin/coupon'} + request_parameter_name='coupon_order' + label="{intl l='Days before expiration'}" + } + {admin_sortable_header + current_order=$coupon_order + order='usages-left' + reverse_order='usages-left-reverse' + path={url path='/admin/coupon'} + request_parameter_name='coupon_order' + label="{intl l='Usages left'}" + } +  
{block name="coupon-code"}{$CODE}{/block}{block name="coupon-title"}{$TITLE}{/block}{block name="coupon-expiration-date"}{$EXPIRATION_DATE}{/block} - {block name="coupon-usage-left"} - {if $USAGE_LEFT == -1} - - {intl l="Unlimited"} - - {elseif $USAGE_LEFT} - - {$USAGE_LEFT} - - {else} - - 0 - - {/if} - {/block} + {loop type="auth" name="can_change" role="ADMIN" resource="admin.coupon" access="UPDATE"} + {$CODE} + {/loop} + {elseloop rel="can_change"} + {$CODE} + {/elseloop} - {block name="coupon-action"} - - {intl l='Edit'} - - {/block} + + {$TITLE} + {if $IS_ENABLED} + {intl l="Enabled"} + {else} + {intl l="Disabled"} + {/if} + {format_date date=$EXPIRATION_DATE output="date"} + {if $DAY_LEFT_BEFORE_EXPIRATION <= 0} + {intl l='Expired'} + {else} + {$DAY_LEFT_BEFORE_EXPIRATION} + {/if} + + {if $USAGE_LEFT == -1} + {intl l="Unlimited"} + {elseif $USAGE_LEFT} + {$USAGE_LEFT} + {else} + 0 + {/if} + + {loop type="auth" name="can_change" role="ADMIN" resource="admin.coupon" access="UPDATE"} + + {/loop}
+ + {module_include location='coupon_bottom'} +
From be8b4abecea922e2350ce4cfab48c86d31abe8fd Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Thu, 1 May 2014 19:22:15 +0200 Subject: [PATCH 05/48] Added close button --- templates/backOffice/default/coupon/form.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/backOffice/default/coupon/form.html b/templates/backOffice/default/coupon/form.html index f6d4365c0..34432ae1e 100644 --- a/templates/backOffice/default/coupon/form.html +++ b/templates/backOffice/default/coupon/form.html @@ -28,7 +28,8 @@ file = "includes/inner-form-toolbar.html" hide_submit_buttons = false - page_url = "{url path="{$formAction}"}" + page_url = {url path=$formAction} + close_url = {url path='/admin/coupon'} } {/if} From 859e9ca60b62c47d75c0da7cd0b2cb0700c8cdeb Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 12:05:32 +0200 Subject: [PATCH 06/48] Using template for coupons HTML fragments --- .../backOffice/default/assets/js/coupon.js | 29 +-- .../backOffice/default/coupon-create.html | 7 +- .../backOffice/default/coupon-update.html | 5 +- .../backOffice/default/coupon/conditions.html | 14 +- templates/backOffice/default/coupon/form.html | 212 +++++++++--------- 5 files changed, 133 insertions(+), 134 deletions(-) diff --git a/templates/backOffice/default/assets/js/coupon.js b/templates/backOffice/default/assets/js/coupon.js index 0bf95b41a..de83da5be 100644 --- a/templates/backOffice/default/assets/js/coupon.js +++ b/templates/backOffice/default/assets/js/coupon.js @@ -4,7 +4,7 @@ $(function($){ $.couponManager = {}; // Condition being updated category id - $.couponManager.conditionToUpdateServiceId = -1; + $.couponManager.conditionToUpdateServiceId = ''; // Condition being updated index $.couponManager.conditionToUpdateIndex = false; @@ -20,6 +20,7 @@ $(function($){ $.couponManager.intlPleaseRetry = ''; $.couponManager.intlPleaseSelectAnotherCondition = ''; $.couponManager.intlDoYouReallyWantToSetCouponAvailableForEveryOne = ''; + $.couponManager.intlDoYouReallyWantToDeleteThisCondition = ''; // ***************************************** // ****************** Delete *************** @@ -28,11 +29,13 @@ $(function($){ $.couponManager.onClickDeleteCondition = function() { $('.condition-delete-btn').on('click', function (e) { e.preventDefault(); - var $this = $(this); - var index = $this.attr('data-conditionIndex'); - $.couponManager.conditionToUpdateServiceId = -1; - $.couponManager.conditionToUpdateIndex = false; - $.couponManager.removeConditionAjax(index); + if (confirm($.couponManager.intlDoYouReallyWantToDeleteThisCondition)) { + var $this = $(this); + var index = $this.data('condition-index'); + $.couponManager.conditionToUpdateServiceId = ''; + $.couponManager.conditionToUpdateIndex = false; + $.couponManager.removeConditionAjax(index); + } }); }; $.couponManager.onClickDeleteCondition(); @@ -94,7 +97,7 @@ $(function($){ $('#condition-add-operators-values').html(''); // Set the condition selector to default $("#category-condition option").filter(function() { - return $(this).val() == '-1'; + return $(this).val() == ''; }).prop('selected', true); }).fail(function() { $('#condition-add-operators-values').html( @@ -115,8 +118,8 @@ $(function($){ $('.condition-update-btn').on('click', function (e) { e.preventDefault(); var $this = $(this); - $.couponManager.conditionToUpdateServiceId = $this.attr('data-serviceId'); - $.couponManager.conditionToUpdateIndex = $this.attr('data-conditionIndex'); + $.couponManager.conditionToUpdateServiceId = $this.data('service-id'); + $.couponManager.conditionToUpdateIndex = $this.data('condition-index'); $.couponManager.updateConditionSelectFromConditionInterfaceAjax( $.couponManager.conditionToUpdateIndex, @@ -135,7 +138,7 @@ $(function($){ var $this = $(this); var mainDiv = $('#condition-add-type'); var optionSelected = $('option:selected', this); - mainDiv.find('.typeToolTip').html(optionSelected.attr('data-description')); + mainDiv.find('.typeToolTip').html(optionSelected.data('description')); // Only if add mode if (false != $.couponManager.conditionToUpdateIndex) { @@ -179,7 +182,7 @@ $(function($){ } }).done(function(data) { $('#condition-add-operators-values').html(data); - if ($.couponManager.conditionToUpdateServiceId == -1) { + if ($.couponManager.conditionToUpdateServiceId == '') { // Placeholder can't be saved $('#condition-save-btn').hide(); } else { @@ -213,7 +216,7 @@ $(function($){ $.couponManager.onEffectChange = function() { var mainDiv = $('#coupon-type'); var optionSelected = mainDiv.find('#type option:selected'); - mainDiv.find('.typeToolTip').html(optionSelected.attr('data-description')); + mainDiv.find('.typeToolTip').html(optionSelected.data('description')); mainDiv.find('#type').on('change', function () { var optionSelected = $('option:selected', this); @@ -225,7 +228,7 @@ $(function($){ $.couponManager.displayEfffect = function(optionSelected) { var mainDiv = $('#coupon-type'); - mainDiv.find('.typeToolTip').html(optionSelected.attr('data-description')); + mainDiv.find('.typeToolTip').html(optionSelected.data('description')); var inputsDiv = mainDiv.find('.inputs'); inputsDiv.html('
'); diff --git a/templates/backOffice/default/coupon-create.html b/templates/backOffice/default/coupon-create.html index 8dab9585e..b57547415 100644 --- a/templates/backOffice/default/coupon-create.html +++ b/templates/backOffice/default/coupon-create.html @@ -17,12 +17,8 @@ - - {form name="thelia.admin.coupon.creation"} - {include file='coupon/form.html' formAction={url path={$formAction}} noConditions=true} + {include file='coupon/form.html' formAction={url path={$formAction}} noConditions=true title={intl l='Create a new coupon'}} {/form} @@ -48,6 +44,7 @@ $.couponManager.urlAjaxAdminCouponDrawInputs = "{$urlAjaxAdminCouponDrawInputs}"; $.couponManager.intlPleaseRetry = '{intl l='Please retry'}'; $.couponManager.intlDoYouReallyWantToSetCouponAvailableForEveryOne = '{intl l='Do you really want to set this coupon available to everyone ?'}'; + $.couponManager.intlDoYouReallyWantToDeleteThisCondition = '{intl l='Do you really want to delete this condition ?'}'; }); diff --git a/templates/backOffice/default/coupon-update.html b/templates/backOffice/default/coupon-update.html index 9a70d6fa0..6a943027c 100644 --- a/templates/backOffice/default/coupon-update.html +++ b/templates/backOffice/default/coupon-update.html @@ -14,12 +14,12 @@
  • {intl l='Home'}
  • {intl l='Tools'}
  • {intl l='Coupon'}
  • -
  • {intl l="Editing %title" title="$couponCode"}
  • +
  • {intl l='Editing coupon "%title"' title="$couponCode"}
  • {form name="thelia.admin.coupon.creation"} - {include file='coupon/form.html' formAction={url path={$formAction}} form=$form noConditions=false} + {include file='coupon/form.html' formAction={url path={$formAction}} form=$form noConditions=false title={intl l='Editing coupon "%title"' title=$couponCode}} {/form} @@ -52,6 +52,7 @@ $.couponManager.intlPleaseRetry = '{intl l='Please retry'}'; $.couponManager.intlPleaseSelectAnotherCondition = '{intl l='Please select another condition'}'; $.couponManager.intlDoYouReallyWantToSetCouponAvailableForEveryOne = '{intl l='Do you really want to set this coupon available to everyone ?'}'; + $.couponManager.intlDoYouReallyWantToDeleteThisCondition = '{intl l='Do you really want to delete this condition ?'}'; $('#condition-save-btn').hide(); }); diff --git a/templates/backOffice/default/coupon/conditions.html b/templates/backOffice/default/coupon/conditions.html index 1ae577e42..5972c0327 100644 --- a/templates/backOffice/default/coupon/conditions.html +++ b/templates/backOffice/default/coupon/conditions.html @@ -1,5 +1,5 @@ {* List all condition with their summary *} -{foreach from=$conditions item=condition key=i name=conditionsForeach} +{foreach from=$conditions item=condition name=conditionsForeach} {if !$smarty.foreach.conditionsForeach.first} @@ -7,13 +7,15 @@ {/if} {$condition.summary nofilter} - - - {intl l='Edit'} + + + + + {if $conditions|count != 1} - - {intl l='Delete'} + + {/if} diff --git a/templates/backOffice/default/coupon/form.html b/templates/backOffice/default/coupon/form.html index 34432ae1e..a90b0df12 100644 --- a/templates/backOffice/default/coupon/form.html +++ b/templates/backOffice/default/coupon/form.html @@ -3,9 +3,10 @@
    +
    -
    - {intl l='Edit %title' title={$couponCode}} +
    + {$title}
    @@ -34,19 +35,12 @@ {/if}
    -
    +
    {form_field form=$form field='code'}
    - + - {if $error}{$message}{/if} -
    - {/form_field} - - {form_field form=$form field='title'} -
    - - + {intl l='This is the code entered by your customers to use this coupon'} {if $error}{$message}{/if}
    {/form_field} @@ -56,7 +50,7 @@
    {/form_field} @@ -66,7 +60,7 @@
    {/form_field} @@ -76,7 +70,7 @@
    {/form_field} @@ -86,7 +80,7 @@
    {/form_field} @@ -107,125 +101,127 @@ - - + + {if $error}{$message}{/if}
    {/form_field}
    -
    -
    -
    - {form_field form=$form field='type'} -
    - - - {if $error}{$message}{/if} - {$availableCoupons.0.toolTip} -
    - {/form_field} -
    +
    -
    +
    + {form_field form=$form field='type'} +
    + + + {if $error}{$message}{/if} + {$availableCoupons.0.toolTip} +
    + {/form_field} + +
    {form_field form=$form field='amount'} - {$couponInputsHtml nofilter} + {$couponInputsHtml nofilter} {/form_field}
    +
    + +
    + + {form_field form=$form field='title'} +
    + + + {if $error}{$message}{/if} +
    + {/form_field} {form_field form=$form field='shortDescription'}
    - + {if $error}{$message}{/if}
    {/form_field} -
    - -
    -
    {form_field form=$form field='description'}
    - + {if $error}{$message}{/if}
    {/form_field} - - {if $noConditions} - - {/if}
    -
    - -
    -
    - - -{if $noConditions} - {include file='includes/notifications.html' message={intl l='Please save your Coupon in oder to affect it some conditions'}} -{else} -
    -
    - -
    - - - - - - - - - - {include file='coupon/conditions.html' conditions=$conditions} - -
    - {intl l='Conditions'} -
    {intl l='Conditions'}{intl l='Actions'}
    -
    - -
    -
    - -
    -
    - -
    -
    -
    - - {intl l='Save this condition'} - - -
    - - - -
    - -
    -
    +
    -
    - -{/if} +
    +
    + {intl l='Coupon conditions'} +
    +
    + +
    + {if $noConditions} +
    +
    + {include file='includes/notifications.html' type='info' dismissable=false message={intl l='Please save this coupon first to define coupon conditions'}} +
    + {else} +
    +
    + + + + + + + + + {include file='coupon/conditions.html' conditions=$conditions} + +
    {intl l='Condition description'}{intl l='Actions'}
    +
    +
    + +
    +
    + +
    + + + +
    + +
    + +
    + + + {intl l='Save this condition'} + + +
    +
    + {/if} +
    + + \ No newline at end of file From 5518c6f0bd38b4df3e75ff562053649ebf1cfe42 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 12:06:21 +0200 Subject: [PATCH 07/48] Using templates for conditions HTML fragments --- core/lib/Thelia/Coupon/BaseFacade.php | 22 +++++++++++++++++++ core/lib/Thelia/Coupon/FacadeInterface.php | 7 ++++++ core/lib/Thelia/Coupon/Type/RemoveXAmount.php | 6 ++--- .../lib/Thelia/Coupon/Type/RemoveXPercent.php | 4 ++-- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/core/lib/Thelia/Coupon/BaseFacade.php b/core/lib/Thelia/Coupon/BaseFacade.php index b137fb7ab..bdc87261d 100644 --- a/core/lib/Thelia/Coupon/BaseFacade.php +++ b/core/lib/Thelia/Coupon/BaseFacade.php @@ -18,6 +18,8 @@ use Symfony\Component\Translation\Translator; use Symfony\Component\Translation\TranslatorInterface; use Thelia\Condition\ConditionEvaluator; use Thelia\Core\HttpFoundation\Request; +use Thelia\Core\Template\ParserInterface; +use Thelia\Core\Template\TemplateHelper; use Thelia\Model\Coupon; use Thelia\Model\CouponQuery; use Thelia\Cart\CartTrait; @@ -43,6 +45,9 @@ class BaseFacade implements FacadeInterface /** @var Translator Service Translator */ protected $translator = null; + /** @var ParserInterface The thelia parser */ + private $parser = null; + /** * Constructor * @@ -197,6 +202,23 @@ class BaseFacade implements FacadeInterface return $this->container->get('thelia.translator'); } + /** + * Return platform Parser + * + * @return ParserInterface + */ + public function getParser() + { + if ($this->parser == null) { + $this->parser = $this->container->get('thelia.parser'); + + // Define the current back-office template that should be used + $this->parser->setTemplateDefinition(TemplateHelper::getInstance()->getActiveAdminTemplate()); + } + + return $this->parser; + } + /** * Return the main currency * THe one used to set prices in BackOffice diff --git a/core/lib/Thelia/Coupon/FacadeInterface.php b/core/lib/Thelia/Coupon/FacadeInterface.php index 35b0c3891..40e4e2948 100644 --- a/core/lib/Thelia/Coupon/FacadeInterface.php +++ b/core/lib/Thelia/Coupon/FacadeInterface.php @@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Translation\TranslatorInterface; use Thelia\Condition\ConditionEvaluator; use Thelia\Core\HttpFoundation\Request; +use Thelia\Core\Template\ParserInterface; use Thelia\Model\Coupon; /** @@ -129,6 +130,12 @@ interface FacadeInterface * @return TranslatorInterface */ public function getTranslator(); + /** + * Return platform ParserInterface + * + * @return ParserInterface + */ + public function getParser(); /** * Return the main currency diff --git a/core/lib/Thelia/Coupon/Type/RemoveXAmount.php b/core/lib/Thelia/Coupon/Type/RemoveXAmount.php index d8d473963..5ee212b27 100644 --- a/core/lib/Thelia/Coupon/Type/RemoveXAmount.php +++ b/core/lib/Thelia/Coupon/Type/RemoveXAmount.php @@ -33,7 +33,7 @@ class RemoveXAmount extends CouponAbstract { return $this->facade ->getTranslator() - ->trans('Remove X amount to total cart', array(), 'coupon'); + ->trans('Fixed Amount Discount', array(), 'coupon'); } /** @@ -45,7 +45,7 @@ class RemoveXAmount extends CouponAbstract { return $this->facade ->getTranslator() - ->trans('Amount removed from the cart', array(), 'coupon'); + ->trans('Discount amount', array(), 'coupon'); } /** @@ -58,7 +58,7 @@ class RemoveXAmount extends CouponAbstract $toolTip = $this->facade ->getTranslator() ->trans( - 'This coupon will remove the entered amount to the customer total checkout. If the discount is superior to the total checkout price the customer will only pay the postage. Unless if the coupon is set to remove postage too.', + 'This coupon will subtracts a set amount from the total cost of an order. If the discount is greater than the total order corst, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.', array(), 'coupon' ); diff --git a/core/lib/Thelia/Coupon/Type/RemoveXPercent.php b/core/lib/Thelia/Coupon/Type/RemoveXPercent.php index 8019e564f..db0a011ea 100644 --- a/core/lib/Thelia/Coupon/Type/RemoveXPercent.php +++ b/core/lib/Thelia/Coupon/Type/RemoveXPercent.php @@ -116,7 +116,7 @@ class RemoveXPercent extends CouponAbstract { return $this->facade ->getTranslator() - ->trans('Percentage removed from the cart', array(), 'coupon'); + ->trans('Percent Discount', array(), 'coupon'); } /** @@ -129,7 +129,7 @@ class RemoveXPercent extends CouponAbstract $toolTip = $this->facade ->getTranslator() ->trans( - 'This coupon will remove the entered percentage to the customer total checkout. If the discount is superior to the total checkout price the customer will only pay the postage. Unless if the coupon is set to remove postage too.', + 'This coupon will offert a flat percentage off a shopper\'s entire order (not applied to shipping costs or tax rates). If the discount is greater than the total order corst, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.', array(), 'coupon' ); From b776a36bbddc2981b2b2b73086b7092369d84db6 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 12:07:17 +0200 Subject: [PATCH 08/48] Fixed labels, using templates for HTML fragments --- .../Thelia/Condition/ConditionCollection.php | 4 +- .../lib/Thelia/Condition/ConditionFactory.php | 2 +- .../Implementation/ConditionAbstract.php | 121 +++++++++--------- .../Implementation/MatchForEveryone.php | 20 +-- .../Implementation/MatchForTotalAmount.php | 79 +++--------- .../Implementation/MatchForXArticles.php | 39 ++---- core/lib/Thelia/Condition/Operators.php | 34 ++--- .../Condition/SerializableCondition.php | 4 +- .../Controller/Admin/CouponController.php | 42 +++--- 9 files changed, 150 insertions(+), 195 deletions(-) diff --git a/core/lib/Thelia/Condition/ConditionCollection.php b/core/lib/Thelia/Condition/ConditionCollection.php index 7b70df07c..d820edfe1 100644 --- a/core/lib/Thelia/Condition/ConditionCollection.php +++ b/core/lib/Thelia/Condition/ConditionCollection.php @@ -27,7 +27,7 @@ use Thelia\Condition\Implementation\ConditionInterface; class ConditionCollection implements Iterator, Countable, ArrayAccess { /** @var array Array of ConditionInterface */ - protected $conditions = array(); + protected $conditions = []; /** * (PHP 5 >= 5.0.0) @@ -180,7 +180,7 @@ class ConditionCollection implements Iterator, Countable, ArrayAccess */ public function __toString() { - $arrayToSerialize = array(); + $arrayToSerialize = []; /** @var ConditionInterface $condition */ foreach ($this as $condition) { $arrayToSerialize[] = $condition->getSerializableCondition(); diff --git a/core/lib/Thelia/Condition/ConditionFactory.php b/core/lib/Thelia/Condition/ConditionFactory.php index 60e2643b9..8fd9647b6 100644 --- a/core/lib/Thelia/Condition/ConditionFactory.php +++ b/core/lib/Thelia/Condition/ConditionFactory.php @@ -61,7 +61,7 @@ class ConditionFactory ); $collection[] = $conditionNone; } - $serializableConditions = array(); + $serializableConditions = []; /** @var $condition ConditionInterface */ foreach ($collection as $condition) { $serializableConditions[] = $condition->getSerializableCondition(); diff --git a/core/lib/Thelia/Condition/Implementation/ConditionAbstract.php b/core/lib/Thelia/Condition/Implementation/ConditionAbstract.php index 5a1f5c71d..5ddf4f6e4 100644 --- a/core/lib/Thelia/Condition/Implementation/ConditionAbstract.php +++ b/core/lib/Thelia/Condition/Implementation/ConditionAbstract.php @@ -18,6 +18,7 @@ use Thelia\Condition\SerializableCondition; use Thelia\Core\Translation\Translator; use Thelia\Coupon\FacadeInterface; use Thelia\Exception\InvalidConditionValueException; +use Thelia\Model\Base\CurrencyQuery; use Thelia\Model\Currency; use Thelia\Type\FloatType; @@ -35,10 +36,10 @@ abstract class ConditionAbstract implements ConditionInterface protected $serviceId = null; /** @var array Available Operators (Operators::CONST) */ - protected $availableOperators = array(); + protected $availableOperators = []; /** @var array Parameters validating parameters against */ - protected $validators = array(); + protected $validators = []; /** @var FacadeInterface Provide necessary value from Thelia */ protected $facade = null; @@ -47,10 +48,10 @@ abstract class ConditionAbstract implements ConditionInterface protected $translator = null; /** @var array Operators set by Admin in BackOffice */ - protected $operators = array(); + protected $operators = []; /** @var array Values set by Admin in BackOffice */ - protected $values = array(); + protected $values = []; /** @var ConditionEvaluator Conditions validator */ protected $conditionValidator = null; @@ -64,6 +65,7 @@ abstract class ConditionAbstract implements ConditionInterface { $this->facade = $facade; $this->translator = $facade->getTranslator(); + $this->parser = $facade->getParser(); $this->conditionValidator = $facade->getConditionEvaluator(); } @@ -86,9 +88,9 @@ abstract class ConditionAbstract implements ConditionInterface { $this->validators = $this->generateInputs(); - $translatedInputs = array(); + $translatedInputs = []; foreach ($this->validators as $key => $validator) { - $translatedOperators = array(); + $translatedOperators = []; foreach ($validator['availableOperators'] as $availableOperators) { $translatedOperators[$availableOperators] = Operators::getI18n( $this->translator, @@ -99,7 +101,7 @@ abstract class ConditionAbstract implements ConditionInterface $validator['availableOperators'] = $translatedOperators; $translatedInputs[$key] = $validator; } - $validators = array(); + $validators = []; $validators['inputs'] = $translatedInputs; $validators['setOperators'] = $this->operators; $validators['setValues'] = $this->values; @@ -216,27 +218,21 @@ abstract class ConditionAbstract implements ConditionInterface */ protected function drawBackOfficeInputOperators($inputKey) { - $selectHtml = ''; - $optionHtml = ''; - $inputs = $this->getValidators(); - if (isset($inputs['inputs'][$inputKey])) { - $operators = $inputs['inputs'][$inputKey]['availableOperators']; - foreach ($operators as $key => $operator) { - $selected = ''; - if (isset($this->operators) && isset($this->operators[$inputKey]) && $this->operators[$inputKey] == $key) { - $selected = ' selected="selected"'; - } - $optionHtml .= ''; - } + $html = ''; - $selectHtml .= ' - - '; + $inputs = $this->getValidators(); + + if (isset($inputs['inputs'][$inputKey])) { + + $html = $this->facade->getParser()->render('coupon/condition-fragments/condition-selector.html', [ + 'operators' => $inputs['inputs'][$inputKey]['availableOperators'], + 'value' => isset($this->operators[$inputKey]) ? $this->operators[$inputKey] : '', + 'inputKey' => $inputKey + ] + ); } - return $selectHtml; + return $html; } /** @@ -251,26 +247,19 @@ abstract class ConditionAbstract implements ConditionInterface protected function drawBackOfficeBaseInputsText($label, $inputKey) { $operatorSelectHtml = $this->drawBackOfficeInputOperators($inputKey); + $currentValue = ''; if (isset($this->values) && isset($this->values[$inputKey])) { $currentValue = $this->values[$inputKey]; } - $html = ' -
    - -
    -
    - ' . $operatorSelectHtml . ' -
    -
    - -
    -
    -
    - '; - - return $html; + return $this->facade->getParser()->render('coupon/conditions-fragments/base-input-text.html', [ + 'label' => $label, + 'inputKey' => $inputKey, + 'currentValue' => $currentValue, + 'operatorSelectHtml' => $operatorSelectHtml + ] + ); } /** @@ -285,23 +274,39 @@ abstract class ConditionAbstract implements ConditionInterface */ protected function drawBackOfficeInputQuantityValues($inputKey, $max = 10, $min = 0) { - $selectHtml = ''; - $optionHtml = ''; - for ($i = $min; $i <= $max; $i++) { - $selected = ''; - if (isset($this->values) && isset($this->values[$inputKey]) && $this->values[$inputKey] == $i) { - $selected = ' selected="selected"'; - } - $optionHtml .= ''; - } - - $selectHtml .= ' - - '; - - return $selectHtml; + return $this->facade->getParser()->render('coupon/condition-fragments/quantity-selector.html', [ + 'min' => $min, + 'max' => $max, + 'value' => isset($this->values[$inputKey]) ? $this->values[$inputKey] : '', + 'inputKey' => $inputKey + ] + ); } -} + /** + * Draw the currency input displayed in the BackOffice + * allowing Admin to set its Coupon Conditions + * + * @param string $inputKey Input key (ex: self::INPUT1) + * + * @return string HTML string + */ + protected function drawBackOfficeCurrencyInput($inputKey) + { + $currencies = CurrencyQuery::create()->find(); + + $cleanedCurrencies = []; + + /** @var Currency $currency */ + foreach ($currencies as $currency) { + $cleanedCurrencies[$currency->getCode()] = $currency->getSymbol(); + } + + return $this->facade->getParser()->render('coupon/condition-fragments/currency-selector.html', [ + 'currencies' => $cleanedCurrencies, + 'value' => isset($this->values[$inputKey]) ? $this->values[$inputKey] : '', + 'inputKey' => $inputKey + ] + ); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Condition/Implementation/MatchForEveryone.php b/core/lib/Thelia/Condition/Implementation/MatchForEveryone.php index a5a3e4d1d..5049470a2 100644 --- a/core/lib/Thelia/Condition/Implementation/MatchForEveryone.php +++ b/core/lib/Thelia/Condition/Implementation/MatchForEveryone.php @@ -25,7 +25,7 @@ class MatchForEveryone extends ConditionAbstract protected $serviceId = 'thelia.condition.match_for_everyone'; /** @var array Available Operators (Operators::CONST) */ - protected $availableOperators = array(); + protected $availableOperators = []; /** * Check validators relevancy and store them @@ -51,8 +51,8 @@ class MatchForEveryone extends ConditionAbstract */ protected function setValidators() { - $this->operators = array(); - $this->values = array(); + $this->operators = []; + $this->values = []; return $this; } @@ -75,8 +75,8 @@ class MatchForEveryone extends ConditionAbstract public function getName() { return $this->translator->trans( - 'Everybody can use it (no condition)', - array(), + 'Unconditional usage', + [], 'condition' ); } @@ -90,8 +90,8 @@ class MatchForEveryone extends ConditionAbstract public function getToolTip() { $toolTip = $this->translator->trans( - 'Will return always true', - array(), + 'This condition is always true', + [], 'condition' ); @@ -107,8 +107,8 @@ class MatchForEveryone extends ConditionAbstract public function getSummary() { $toolTip = $this->translator->trans( - 'Will return always true', - array(), + 'Unconditionnal usage', + [], 'condition' ); @@ -122,7 +122,7 @@ class MatchForEveryone extends ConditionAbstract */ protected function generateInputs() { - return array(); + return []; } /** diff --git a/core/lib/Thelia/Condition/Implementation/MatchForTotalAmount.php b/core/lib/Thelia/Condition/Implementation/MatchForTotalAmount.php index 5c26ee75b..6b4b48f15 100644 --- a/core/lib/Thelia/Condition/Implementation/MatchForTotalAmount.php +++ b/core/lib/Thelia/Condition/Implementation/MatchForTotalAmount.php @@ -153,7 +153,7 @@ class MatchForTotalAmount extends ConditionAbstract { return $this->translator->trans( 'By cart total amount', - array(), + [], 'condition' ); } @@ -168,7 +168,7 @@ class MatchForTotalAmount extends ConditionAbstract { $toolTip = $this->translator->trans( 'Check the total Cart amount in the given currency', - array(), + [], 'condition' ); @@ -208,7 +208,7 @@ class MatchForTotalAmount extends ConditionAbstract protected function generateInputs() { $currencies = CurrencyQuery::create()->find(); - $cleanedCurrencies = array(); + $cleanedCurrencies = []; /** @var Currency $currency */ foreach ($currencies as $currency) { $cleanedCurrencies[$currency->getCode()] = $currency->getSymbol(); @@ -240,7 +240,7 @@ class MatchForTotalAmount extends ConditionAbstract { $labelPrice = $this->facade ->getTranslator() - ->trans('Price', array(), 'condition'); + ->trans('Cart total amount is', [], 'condition'); $html = $this->drawBackOfficeBaseInputsText($labelPrice, self::INPUT1); @@ -258,66 +258,17 @@ class MatchForTotalAmount extends ConditionAbstract */ protected function drawBackOfficeBaseInputsText($label, $inputKey) { - $operatorSelectHtml = $this->drawBackOfficeInputOperators(self::INPUT1); - $currencySelectHtml = $this->drawBackOfficeCurrencyInput(self::INPUT2); - $selectedAmount = ''; - if (isset($this->values) && isset($this->values[$inputKey])) { - $selectedAmount = $this->values[$inputKey]; - } + return $this->facade->getParser()->render('coupon/condition-fragments/cart-total-amount-condition.html', [ + 'label' => $label, + 'inputKey' => $inputKey, + 'value' => isset($this->values[$inputKey]) ? $this->values[$inputKey] : '', - $html = ' - -
    -
    - ' . $operatorSelectHtml . ' -
    -
    - -
    -
    - - ' . $currencySelectHtml . ' -
    -
    - '; + 'field_1_name' => self::INPUT1, + 'field_2_name' => self::INPUT2, - return $html; + 'operatorSelectHtml' => $this->drawBackOfficeInputOperators(self::INPUT1), + 'currencySelectHtml' => $this->drawBackOfficeCurrencyInput(self::INPUT2), + ] + ); } - - /** - * Draw the currency input displayed in the BackOffice - * allowing Admin to set its Coupon Conditions - * - * @param string $inputKey Input key (ex: self::INPUT1) - * - * @return string HTML string - */ - protected function drawBackOfficeCurrencyInput($inputKey) - { - $optionHtml = ''; - - $currencies = CurrencyQuery::create()->find(); - $cleanedCurrencies = array(); - /** @var Currency $currency */ - foreach ($currencies as $currency) { - $cleanedCurrencies[$currency->getCode()] = $currency->getSymbol(); - } - - foreach ($cleanedCurrencies as $key => $cleanedCurrency) { - $selected = ''; - if (isset($this->values) && isset($this->values[$inputKey]) && $this->values[$inputKey] == $key) { - $selected = ' selected="selected"'; - } - $optionHtml .= ''; - } - - $selectHtml = ' - - '; - - return $selectHtml; - } - -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Condition/Implementation/MatchForXArticles.php b/core/lib/Thelia/Condition/Implementation/MatchForXArticles.php index dec3fff29..0e7c9d832 100644 --- a/core/lib/Thelia/Condition/Implementation/MatchForXArticles.php +++ b/core/lib/Thelia/Condition/Implementation/MatchForXArticles.php @@ -127,8 +127,8 @@ class MatchForXArticles extends ConditionAbstract public function getName() { return $this->translator->trans( - 'By number of articles in cart', - array(), + 'Cart item count condition', + [], 'condition' ); } @@ -142,8 +142,8 @@ class MatchForXArticles extends ConditionAbstract public function getToolTip() { $toolTip = $this->translator->trans( - 'Check the amount of product in the Cart', - array(), + 'The cart item count should match the condition', + [], 'condition' ); @@ -163,7 +163,7 @@ class MatchForXArticles extends ConditionAbstract ); $toolTip = $this->translator->trans( - 'If cart products quantity is %operator% %quantity%', + 'If cart item count is %operator% %quantity%', array( '%operator%' => $i18nOperator, '%quantity%' => $this->values[self::INPUT1] @@ -200,7 +200,7 @@ class MatchForXArticles extends ConditionAbstract { $labelQuantity = $this->facade ->getTranslator() - ->trans('Quantity', array(), 'condition'); + ->trans('Cart item count is', [], 'condition'); $html = $this->drawBackOfficeBaseInputsText($labelQuantity, self::INPUT1); @@ -218,24 +218,11 @@ class MatchForXArticles extends ConditionAbstract */ protected function drawBackOfficeBaseInputsText($label, $inputKey) { - $operatorSelectHtml = $this->drawBackOfficeInputOperators($inputKey); - $quantitySelectHtml = $this->drawBackOfficeInputQuantityValues($inputKey, 20, 1); - - $html = ' -
    - -
    -
    - ' . $operatorSelectHtml . ' -
    -
    - ' . $quantitySelectHtml . ' -
    -
    -
    - '; - - return $html; + return $this->facade->getParser()->render('coupon/condition-fragments/cart-item-count-condition.html', [ + 'label' => $label, + 'operatorSelectHtml' => $this->drawBackOfficeInputOperators($inputKey), + 'quantitySelectHtml' => $this->drawBackOfficeInputQuantityValues($inputKey, 20, 1) + ] + ); } - -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Condition/Operators.php b/core/lib/Thelia/Condition/Operators.php index 5d1801839..7d2ae1485 100644 --- a/core/lib/Thelia/Condition/Operators.php +++ b/core/lib/Thelia/Condition/Operators.php @@ -54,57 +54,57 @@ abstract class Operators switch ($operator) { case self::INFERIOR: $ret = $translator->trans( - 'inferior to', - array(), + 'Less than', + [], 'condition' ); break; case self::INFERIOR_OR_EQUAL: $ret = $translator->trans( - 'inferior or equal to', - array(), + 'Less than or equals', + [], 'condition' ); break; case self::EQUAL: $ret = $translator->trans( - 'equal to', - array(), + 'Equals to', + [], 'condition' ); break; case self::SUPERIOR_OR_EQUAL: $ret = $translator->trans( - 'superior or equal to', - array(), + 'Greater than or equals', + [], 'condition' ); break; case self::SUPERIOR: $ret = $translator->trans( - 'superior to', - array(), + 'Greater than', + [], 'condition' ); break; case self::DIFFERENT: $ret = $translator->trans( - 'different from', - array(), + 'Not equals', + [], 'condition' ); break; case self::IN: $ret = $translator->trans( - 'in', - array(), + 'In', + [], 'condition' ); break; case self::OUT: $ret = $translator->trans( - 'not in', - array(), + 'Not in', + [], 'condition' ); break; @@ -113,4 +113,4 @@ abstract class Operators return $ret; } -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Condition/SerializableCondition.php b/core/lib/Thelia/Condition/SerializableCondition.php index 0e921388f..8d8cf4a7d 100644 --- a/core/lib/Thelia/Condition/SerializableCondition.php +++ b/core/lib/Thelia/Condition/SerializableCondition.php @@ -25,9 +25,9 @@ class SerializableCondition public $conditionServiceId = null; /** @var array Operators set by Admin for this Condition */ - public $operators = array(); + public $operators = []; /** @var array Values set by Admin for this Condition */ - public $values = array(); + public $values = []; } diff --git a/core/lib/Thelia/Controller/Admin/CouponController.php b/core/lib/Thelia/Controller/Admin/CouponController.php index 82c3a97d5..6ecd418e8 100644 --- a/core/lib/Thelia/Controller/Admin/CouponController.php +++ b/core/lib/Thelia/Controller/Admin/CouponController.php @@ -292,30 +292,42 @@ class CouponController extends BaseAdminController */ public function getConditionEmptyInputAjaxAction($conditionId) { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) + return $response; $this->checkXmlHttpRequest(); - /** @var ConditionFactory $conditionFactory */ - $conditionFactory = $this->container->get('thelia.condition.factory'); - $inputs = $conditionFactory->getInputsFromServiceId($conditionId); - if (!$this->container->has($conditionId)) { - return false; + if (! empty($conditionId)) { + + /** @var ConditionFactory $conditionFactory */ + $conditionFactory = $this->container->get('thelia.condition.factory'); + $inputs = $conditionFactory->getInputsFromServiceId($conditionId); + + if (!$this->container->has($conditionId)) { + return false; + } + + if ($inputs === null) { + return $this->pageNotFound(); + } + + /** @var ConditionInterface $condition */ + $condition = $this->container->get($conditionId); + + $html = $condition->drawBackOfficeInputs(); + $serviceId = $condition->getServiceId(); } - - /** @var ConditionInterface $condition */ - $condition = $this->container->get($conditionId); - - if ($inputs === null) { - return $this->pageNotFound(); + else { + $html = ''; + $serviceId = ''; } return $this->render( 'coupon/condition-input-ajax', array( - 'inputsDrawn' => $condition->drawBackOfficeInputs(), - 'conditionServiceId' => $condition->getServiceId(), - 'conditionIndex' => -1, + 'inputsDrawn' => $html, + 'conditionServiceId' => $serviceId, + 'conditionIndex' => '', ) ); } From 6d533149af0daabe8b56fbebe52b2d6cf731ed09 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 12:08:22 +0200 Subject: [PATCH 09/48] Coupons conditions HTML fragments --- .../condition-fragments/base-input-text.html | 11 ++++++++++ .../cart-item-count-condition.html | 11 ++++++++++ .../cart-total-amount-condition.html | 20 +++++++++++++++++++ .../condition-selector.html | 5 +++++ .../currency-selector.html | 5 +++++ .../quantity-selector.html | 9 +++++++++ 6 files changed, 61 insertions(+) create mode 100644 templates/backOffice/default/coupon/condition-fragments/base-input-text.html create mode 100644 templates/backOffice/default/coupon/condition-fragments/cart-item-count-condition.html create mode 100644 templates/backOffice/default/coupon/condition-fragments/cart-total-amount-condition.html create mode 100644 templates/backOffice/default/coupon/condition-fragments/condition-selector.html create mode 100644 templates/backOffice/default/coupon/condition-fragments/currency-selector.html create mode 100644 templates/backOffice/default/coupon/condition-fragments/quantity-selector.html diff --git a/templates/backOffice/default/coupon/condition-fragments/base-input-text.html b/templates/backOffice/default/coupon/condition-fragments/base-input-text.html new file mode 100644 index 000000000..422ae441a --- /dev/null +++ b/templates/backOffice/default/coupon/condition-fragments/base-input-text.html @@ -0,0 +1,11 @@ +
    + +
    +
    + {$operatorSelectHtml nofilter} +
    +
    + +
    +
    +
    \ No newline at end of file diff --git a/templates/backOffice/default/coupon/condition-fragments/cart-item-count-condition.html b/templates/backOffice/default/coupon/condition-fragments/cart-item-count-condition.html new file mode 100644 index 000000000..199fd11b8 --- /dev/null +++ b/templates/backOffice/default/coupon/condition-fragments/cart-item-count-condition.html @@ -0,0 +1,11 @@ +
    + +
    +
    + {$operatorSelectHtml nofilter} +
    +
    + {$quantitySelectHtml nofilter} +
    +
    +
    \ No newline at end of file diff --git a/templates/backOffice/default/coupon/condition-fragments/cart-total-amount-condition.html b/templates/backOffice/default/coupon/condition-fragments/cart-total-amount-condition.html new file mode 100644 index 000000000..53530f14e --- /dev/null +++ b/templates/backOffice/default/coupon/condition-fragments/cart-total-amount-condition.html @@ -0,0 +1,20 @@ +
    + + + +
    +
    + {$operatorSelectHtml nofilter} +
    + +
    + +
    + +
    + + {$currencySelectHtml nofilter} +
    +
    + +
    \ No newline at end of file diff --git a/templates/backOffice/default/coupon/condition-fragments/condition-selector.html b/templates/backOffice/default/coupon/condition-fragments/condition-selector.html new file mode 100644 index 000000000..d1df54d97 --- /dev/null +++ b/templates/backOffice/default/coupon/condition-fragments/condition-selector.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/templates/backOffice/default/coupon/condition-fragments/currency-selector.html b/templates/backOffice/default/coupon/condition-fragments/currency-selector.html new file mode 100644 index 000000000..70b39addf --- /dev/null +++ b/templates/backOffice/default/coupon/condition-fragments/currency-selector.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/templates/backOffice/default/coupon/condition-fragments/quantity-selector.html b/templates/backOffice/default/coupon/condition-fragments/quantity-selector.html new file mode 100644 index 000000000..1da60de16 --- /dev/null +++ b/templates/backOffice/default/coupon/condition-fragments/quantity-selector.html @@ -0,0 +1,9 @@ + +{* Use a text field instead + +*} + From 0c1c08aba09228f715cc7cf8998cb709d75aeed2 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 12:23:40 +0200 Subject: [PATCH 10/48] Adding some padding to error texts --- .../backOffice/default/general_error.html | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/templates/backOffice/default/general_error.html b/templates/backOffice/default/general_error.html index 503cc4106..cefed6cb5 100644 --- a/templates/backOffice/default/general_error.html +++ b/templates/backOffice/default/general_error.html @@ -1,24 +1,24 @@ -{extends file="admin-layout.tpl"} - -{* -- We do not check admin login on this page *} -{block name="check-auth"}{/block} - -{block name="page-title"}{intl l='An error occured'}{/block} - -{block name="main-content"} -
    - -
    -
    -
    -

    {intl l="Oops! An Error Occurred"}

    - - {block name="error-message"}

    {$error_message}

    {/block} - - {intl l="Go to administration home"} -
    -
    -
    - -
    +{extends file="admin-layout.tpl"} + +{* -- We do not check admin login on this page *} +{block name="check-auth"}{/block} + +{block name="page-title"}{intl l='An error occured'}{/block} + +{block name="main-content"} +
    + +
    +
    +
    +

    {intl l="Oops! An Error Occurred"}

    + + {block name="error-message"}

    {$error_message}

    {/block} + + {intl l="Go to administration home"} +
    +
    +
    + +
    {/block} \ No newline at end of file From 7c1c3541b04e58f1046ba777e3bca43a48717cfc Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 12:24:11 +0200 Subject: [PATCH 11/48] Removed the useless coupon read function --- .../Thelia/Config/Resources/routing/admin.xml | 6 +- .../Controller/Admin/CouponController.php | 79 +++----- templates/backOffice/default/coupon-read.html | 173 ------------------ 3 files changed, 23 insertions(+), 235 deletions(-) delete mode 100644 templates/backOffice/default/coupon-read.html diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index aff2e8a5b..348c1d7ec 100644 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -512,10 +512,6 @@ Thelia\Controller\Admin\CouponController::updateAction \d+ - - Thelia\Controller\Admin\CouponController::readAction - \d+ - Thelia\Controller\Admin\CouponController::getBackOfficeInputsAjaxAction .* @@ -549,7 +545,7 @@ - + Thelia\Controller\Admin\ConfigurationController::indexAction diff --git a/core/lib/Thelia/Controller/Admin/CouponController.php b/core/lib/Thelia/Controller/Admin/CouponController.php index 6ecd418e8..695c7c868 100644 --- a/core/lib/Thelia/Controller/Admin/CouponController.php +++ b/core/lib/Thelia/Controller/Admin/CouponController.php @@ -53,58 +53,15 @@ class CouponController extends BaseAdminController */ public function browseAction() { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); - - $args['urlReadCoupon'] = $this->getRoute( - 'admin.coupon.read', - array('couponId' => 0), - Router::ABSOLUTE_URL - ); - - $args['urlEditCoupon'] = $this->getRoute( - 'admin.coupon.update', - array('couponId' => 0), - Router::ABSOLUTE_URL - ); - - $args['urlCreateCoupon'] = $this->getRoute( - 'admin.coupon.create', - array(), - Router::ABSOLUTE_URL - ); + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) { + return $response; + } $args['coupon_order'] = $this->getListOrderFromSession('coupon', 'coupon_order', 'code'); return $this->render('coupon-list', $args); } - /** - * Manage Coupons read display - * - * @param int $couponId Coupon Id - * - * @return \Thelia\Core\HttpFoundation\Response - */ - public function readAction($couponId) - { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); - - $coupon = CouponQuery::create()->findPk($couponId); - - if ($coupon === null) { - return $this->pageNotFound(); - } - - $args['couponId'] = $couponId; - $args['urlEditCoupon'] = $this->getRoute( - 'admin.coupon.update', - array('couponId' => $couponId), - Router::ABSOLUTE_URL - ); - - return $this->render('coupon-read', $args); - } - /** * Manage Coupons creation display * @@ -112,9 +69,7 @@ class CouponController extends BaseAdminController */ public function createAction() { - // Check current user authorization - $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::CREATE); - if ($response !== null) { + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::CREATE)) { return $response; } @@ -165,9 +120,7 @@ class CouponController extends BaseAdminController */ public function updateAction($couponId) { - // Check current user authorization - $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::UPDATE); - if ($response !== null) { + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::UPDATE)) { return $response; } @@ -342,7 +295,9 @@ class CouponController extends BaseAdminController */ public function getConditionToUpdateInputAjaxAction($couponId, $conditionIndex) { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) { + return $response; + } $this->checkXmlHttpRequest(); @@ -396,7 +351,9 @@ class CouponController extends BaseAdminController */ public function saveConditionsAction($couponId) { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::UPDATE)) { + return $response; + } $this->checkXmlHttpRequest(); @@ -443,7 +400,9 @@ class CouponController extends BaseAdminController */ public function deleteConditionsAction($couponId, $conditionIndex) { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::UPDATE)) { + return $response; + } $this->checkXmlHttpRequest(); @@ -681,7 +640,10 @@ class CouponController extends BaseAdminController */ public function getBackOfficeInputsAjaxAction($couponServiceId) { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) { + return $response; + } + $this->checkXmlHttpRequest(); /** @var CouponInterface $coupon */ @@ -706,7 +668,10 @@ class CouponController extends BaseAdminController */ public function getBackOfficeConditionSummariesAjaxAction($couponId) { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) { + return $response; + } + $this->checkXmlHttpRequest(); /** @var Coupon $coupon */ diff --git a/templates/backOffice/default/coupon-read.html b/templates/backOffice/default/coupon-read.html deleted file mode 100644 index 3492bd605..000000000 --- a/templates/backOffice/default/coupon-read.html +++ /dev/null @@ -1,173 +0,0 @@ -{extends file="admin-layout.tpl"} - -{block name="check-resource"}admin.coupon{/block} -{block name="check-access"}view{/block} - -{block name="page-title"}{intl l='Coupon'}{/block} - -{block name="main-content"} -
    - -
    - - {loop type="coupon" name="read_coupon" id={$couponId} backend_context="true"} - - -
    -
    -
    -
    - - {if !$IS_ENABLED} -
    - - {intl l='This coupon is disabled, you can enable at the bottom of this form.'} -
    - {/if} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {intl l='Title'}{$TITLE}
    - {if $IS_ENABLED} - - {intl l="Is enabled"} - - {else} - - {intl l="Is disabled"} - - {/if} -
    - {$SUMMARY} -
    {intl l='Amount'}{$AMOUNT}
    {intl l='Expiration date'}{$EXPIRATION_DATE} ({$DAY_LEFT_BEFORE_EXPIRATION} {intl l="days left"})
    {intl l='Usage left'} - {if $USAGE_LEFT == -1} - - {intl l="Unlimited"} - - {elseif $USAGE_LEFT} - - {$USAGE_LEFT} - - {else} - - 0 - - {/if} -
    - {if $IS_CUMULATIVE} - - {intl l="May be cumulative"} - - {else} - - {intl l="Can't be cumulative"} - - {/if} -
    - {if $IS_REMOVING_POSTAGE} - - {intl l="Will remove postage"} - - {else} - - {intl l="Won't remove postage"} - - {/if} -
    - {if $IS_AVAILABLE_ON_SPECIAL_OFFERS} - - {intl l="Will be available on special offers"} - - {else} - - {intl l="Won't be available on special offers"} - - {/if} -
    {intl l='Application field'} -
      - {foreach from=$APPLICATION_CONDITIONS item=condition name=conditionsForeach} - {if !$smarty.foreach.conditionsForeach.first} -
    • {intl l='And'}
    • - {/if} -
    • {$condition nofilter}
    • - {/foreach} -
    -
    {$SHORT_DESCRIPTION}
    {$DESCRIPTION}
    - - {intl l='Edit'} - -
    -
    -
    -
    -
    - {/loop} -
    -
    - -{include file='includes/confirmation-modal.html' id="enable" message="{intl l='Do you really want to enable this element ?'}"} - -{/block} - -{block name="javascript-initialization"} - {javascripts file='assets/js/main.js'} - - {/javascripts} - -{/block} - -{block name="javascript-last-call"} - {module_include location='coupon-read-js'} -{/block} From c59b45feefb0e401fbbf0f12f98ec89c06b09201 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Tue, 29 Apr 2014 15:01:18 +0200 Subject: [PATCH 12/48] Fixed potiential javascript error --- templates/backOffice/default/ajax/product-related-tab.html | 4 ++-- templates/backOffice/default/category-edit.html | 2 +- templates/backOffice/default/content-edit.html | 2 +- templates/backOffice/default/folder-edit.html | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/templates/backOffice/default/ajax/product-related-tab.html b/templates/backOffice/default/ajax/product-related-tab.html index 1d3efb78e..89b7b554d 100644 --- a/templates/backOffice/default/ajax/product-related-tab.html +++ b/templates/backOffice/default/ajax/product-related-tab.html @@ -560,12 +560,12 @@ $(function() { } }); - // Initialize folder (id={$folder_id}) select value + // Initialize folder select value {if $folder_id != 0} $('#folder_id').val("{$folder_id}").change(); {/if} - // Initialize accessory category id (id={$accessory_category_id}) select value + // Initialize accessory category id select value {if $accessory_category_id != 0} $('#accessory_category_id').val("{$accessory_category_id}").change(); {/if} diff --git a/templates/backOffice/default/category-edit.html b/templates/backOffice/default/category-edit.html index b245ecc04..af50e6c14 100644 --- a/templates/backOffice/default/category-edit.html +++ b/templates/backOffice/default/category-edit.html @@ -380,7 +380,7 @@ $(function() { } }); - // Initialize folder (id={$folder_id}) select value + // Initialize folder select value {if $folder_id != 0} $('#folder_id').val("{$folder_id}").change(); {/if} diff --git a/templates/backOffice/default/content-edit.html b/templates/backOffice/default/content-edit.html index b42b8d56a..87570e8a6 100644 --- a/templates/backOffice/default/content-edit.html +++ b/templates/backOffice/default/content-edit.html @@ -268,7 +268,7 @@ form_content = {$smarty.capture.delete_folder_dialog nofilter} }); }); - // Initialize folder (id= + // Initialize folder select value {if $folder_id != 0} $('#folder_id').val("{$folder_id}").change(); {/if} diff --git a/templates/backOffice/default/folder-edit.html b/templates/backOffice/default/folder-edit.html index 2a22d3741..d5b58625b 100644 --- a/templates/backOffice/default/folder-edit.html +++ b/templates/backOffice/default/folder-edit.html @@ -226,7 +226,7 @@ }); }); - // Initialize folder (id={$folder_id}) select value + // Initialize folder select value {if $folder_id != 0} $('#folder_id').val("{$folder_id}").change(); {/if} From 794b160cc872981e2aaf76637765d4c0b1294039 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Tue, 29 Apr 2014 19:07:06 +0200 Subject: [PATCH 13/48] Removed check of admin.image/document, whis is not managed in the back-office --- templates/backOffice/default/document-edit.html | 1 - templates/backOffice/default/image-edit.html | 1 - 2 files changed, 2 deletions(-) diff --git a/templates/backOffice/default/document-edit.html b/templates/backOffice/default/document-edit.html index 06d055757..b39cf1aee 100644 --- a/templates/backOffice/default/document-edit.html +++ b/templates/backOffice/default/document-edit.html @@ -2,7 +2,6 @@ {block name="page-title"}{intl l='Edit a document'}{/block} -{block name="check-resource"}admin.document{/block} {block name="check-access"}update{/block} {block name="main-content"} diff --git a/templates/backOffice/default/image-edit.html b/templates/backOffice/default/image-edit.html index bb6bbf7f3..88c7cc5a1 100644 --- a/templates/backOffice/default/image-edit.html +++ b/templates/backOffice/default/image-edit.html @@ -2,7 +2,6 @@ {block name="page-title"}{intl l='Edit an image'}{/block} -{block name="check-resource"}admin.image{/block} {block name="check-access"}update{/block} {block name="main-content"} From d54dd4d054c258d87447fc73aa3fdcf13b59f8d4 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Thu, 1 May 2014 19:20:00 +0200 Subject: [PATCH 14/48] Added order parameter, improved request --- core/lib/Thelia/Core/Template/Loop/Coupon.php | 92 +++++++++++++++++-- 1 file changed, 84 insertions(+), 8 deletions(-) diff --git a/core/lib/Thelia/Core/Template/Loop/Coupon.php b/core/lib/Thelia/Core/Template/Loop/Coupon.php index d69d449e5..6885463eb 100644 --- a/core/lib/Thelia/Core/Template/Loop/Coupon.php +++ b/core/lib/Thelia/Core/Template/Loop/Coupon.php @@ -25,6 +25,9 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Coupon\Type\CouponInterface; use Thelia\Model\Coupon as MCoupon; use Thelia\Model\CouponQuery; +use Thelia\Model\Map\CouponTableMap; +use Thelia\Type\EnumListType; +use Thelia\Type\TypeCollection; /** * Coupon Loop @@ -44,7 +47,23 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface { return new ArgumentCollection( Argument::createIntListTypeArgument('id'), - Argument::createBooleanOrBothTypeArgument('is_enabled') + Argument::createBooleanOrBothTypeArgument('is_enabled'), + new Argument( + 'order', + new TypeCollection( + new EnumListType(array( + 'id', 'id-reverse', + 'code', 'code-reverse', + 'title', 'title-reverse', + 'enabled', 'enabled-reverse', + 'expiration-date', 'expiration-date-reverse', + 'days-left', 'days-left-reverse', + 'usages-left', 'usages-left-reverse' + ) + ) + ), + 'code' + ) ); } @@ -66,6 +85,63 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface $search->filterByIsEnabled($isEnabled ? true : false); } + $search->addAsColumn('days_left', 'DATEDIFF('.CouponTableMap::EXPIRATION_DATE.', CURDATE()) - 1'); + + $orders = $this->getOrder(); + + foreach ($orders as $order) { + switch ($order) { + case 'id': + $search->orderById(Criteria::ASC); + break; + case 'id-reverse': + $search->orderById(Criteria::DESC); + break; + + case 'code': + $search->orderByCode(Criteria::ASC); + break; + case 'code-reverse': + $search->orderByCode(Criteria::DESC); + break; + + case 'title': + $search->addAscendingOrderByColumn('i18n_TITLE'); + break; + case 'title-reverse': + $search->addDescendingOrderByColumn('i18n_TITLE'); + break; + + case 'enabled': + $search->orderByIsEnabled(Criteria::ASC); + break; + case 'enabled-reverse': + $search->orderByIsEnabled(Criteria::DESC); + break; + + case 'expiration-date': + $search->orderByExpirationDate(Criteria::ASC); + break; + case 'expiration-date-reverse': + $search->orderByExpirationDate(Criteria::DESC); + break; + + case 'usages-left': + $search->orderByMaxUsage(Criteria::ASC); + break; + case 'usages-left-reverse': + $search->orderByMaxUsage(Criteria::DESC); + break; + + case 'days-left': + $search->addAscendingOrderByColumn('days_left'); + break; + case 'days-left-reverse': + $search->addDescendingOrderByColumn('days_left'); + break; + } + } + return $search; } @@ -81,7 +157,9 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface /** @var MCoupon $coupon */ foreach ($loopResult->getResultDataCollection() as $coupon) { + $loopResultRow = new LoopResultRow($coupon); + $conditions = $conditionFactory->unserializeConditionCollection( $coupon->getSerializedConditions() ); @@ -103,10 +181,6 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface $coupon->getExpirationDate() ); - $now = time(); - $datediff = $coupon->getExpirationDate()->getTimestamp() - $now; - $daysLeftBeforeExpiration = floor($datediff/(60*60*24)); - $cleanedConditions = array(); /** @var ConditionInterface $condition */ foreach ($conditions as $condition) { @@ -116,14 +190,16 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface ); $cleanedConditions[] = $temp; } - $loopResultRow->set("ID", $coupon->getId()) + + $loopResultRow + ->set("ID", $coupon->getId()) ->set("IS_TRANSLATED", $coupon->getVirtualColumn('IS_TRANSLATED')) ->set("LOCALE", $this->locale) ->set("CODE", $coupon->getCode()) ->set("TITLE", $coupon->getVirtualColumn('i18n_TITLE')) ->set("SHORT_DESCRIPTION", $coupon->getVirtualColumn('i18n_SHORT_DESCRIPTION')) ->set("DESCRIPTION", $coupon->getVirtualColumn('i18n_DESCRIPTION')) - ->set("EXPIRATION_DATE", $coupon->getExpirationDate($lang->getDateFormat())) + ->set("EXPIRATION_DATE", $coupon->getExpirationDate()) ->set("USAGE_LEFT", $coupon->getMaxUsage()) ->set("IS_CUMULATIVE", $coupon->getIsCumulative()) ->set("IS_REMOVING_POSTAGE", $coupon->getIsRemovingPostage()) @@ -132,7 +208,7 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface ->set("AMOUNT", $coupon->getAmount()) ->set("APPLICATION_CONDITIONS", $cleanedConditions) ->set("TOOLTIP", $couponManager->getToolTip()) - ->set("DAY_LEFT_BEFORE_EXPIRATION", $daysLeftBeforeExpiration) + ->set("DAY_LEFT_BEFORE_EXPIRATION", max(0, $coupon->getVirtualColumn('days_left'))) ->set("SERVICE_ID", $couponManager->getServiceId()); $loopResult->addRow($loopResultRow); } From 70671c694946978d148b3f14032d2475ee2b5f77 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Thu, 1 May 2014 19:20:32 +0200 Subject: [PATCH 15/48] Normalized coupon list appearance, added sorting --- .../Controller/Admin/CouponController.php | 3 +- templates/backOffice/default/coupon-list.html | 203 ++++++++++-------- 2 files changed, 117 insertions(+), 89 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/CouponController.php b/core/lib/Thelia/Controller/Admin/CouponController.php index 2f2ad63db..82c3a97d5 100644 --- a/core/lib/Thelia/Controller/Admin/CouponController.php +++ b/core/lib/Thelia/Controller/Admin/CouponController.php @@ -73,6 +73,8 @@ class CouponController extends BaseAdminController Router::ABSOLUTE_URL ); + $args['coupon_order'] = $this->getListOrderFromSession('coupon', 'coupon_order', 'code'); + return $this->render('coupon-list', $args); } @@ -856,5 +858,4 @@ class CouponController extends BaseAdminController ) ); } - } diff --git a/templates/backOffice/default/coupon-list.html b/templates/backOffice/default/coupon-list.html index 4ba344601..30a3327b7 100644 --- a/templates/backOffice/default/coupon-list.html +++ b/templates/backOffice/default/coupon-list.html @@ -14,22 +14,25 @@ + {module_include location='coupon_top'} +
    + - - - - - - - - - {loop type="coupon" name="list_coupon" is_enabled="1" backend_context="true"} - - - - - - - - {/loop} - -
    - {intl l='Enabled coupons'} + {intl l='Coupons'} {module_include location='coupon_list_caption'} {loop type="auth" name="can_create" role="ADMIN" resource="admin.coupon" access="CREATE"} - + {/loop} @@ -37,98 +40,119 @@
    {block name="coupon-label-code"}{intl l='Code'}{/block}{block name="coupon-label-title"}{intl l='Title'}{/block}{block name="coupon-label-expiration-date"}{intl l='Days before expiration'}{/block}{block name="coupon-label-usage-left"}{intl l='Usage left'}{/block}{block name="coupon-label-action"}{/block}
    {block name="coupon-code"}{$CODE}{/block}{block name="coupon-title"}{$TITLE}{/block}{block name="coupon-expiration-date"}{$DAY_LEFT_BEFORE_EXPIRATION}{/block} - {block name="coupon-usage-left"} - {if $USAGE_LEFT == -1} - - {intl l="Unlimited"} - - {elseif $USAGE_LEFT} - - {$USAGE_LEFT} - - {else} - - 0 - - {/if} - {/block} - - {block name="coupon-action"} - - {intl l='Edit'} - - {/block} -
    -
    -
    -
    -
    + {admin_sortable_header + current_order=$coupon_order + order='code' + reverse_order='code-reverse' + path={url path='/admin/coupon'} + request_parameter_name='coupon_order' + label="{intl l='Code'}" + } + -
    -
    -
    -
    - - - - - - - - - + + + + + + + + + + + {module_include location='coupon_table_header'} + + - {loop type="coupon" name="list_coupon" is_enabled="0" backend_context="true"} + {loop type="coupon" name="list_coupon" order={$coupon_order|default:'code'} backend_context="true"} - - - - + + + + + + + + + + {module_include location='coupon_table_row'} + + {/loop} @@ -136,6 +160,9 @@
    - {intl l='Disabled coupons'} -
    {block name="coupon-label-code"}{intl l='Code'}{/block}{block name="coupon-label-title"}{intl l='Title'}{/block}{block name="coupon-label-expiration-date"}{intl l='Expiration date'}{/block}{block name="coupon-label-usage-left"}{intl l='Usage left'}{/block}{block name="coupon-label-action"}{/block}{admin_sortable_header + current_order=$coupon_order + order='title' + reverse_order='title-reverse' + path={url path='/admin/coupon'} + request_parameter_name='coupon_order' + label="{intl l='Title'}" + } + {admin_sortable_header + current_order=$coupon_order + order='enabled' + reverse_order='enabled-reverse' + path={url path='/admin/coupon'} + request_parameter_name='coupon_order' + label="{intl l='Status'}" + } + {admin_sortable_header + current_order=$coupon_order + order='expiration-date' + reverse_order='expiration-date-reverse' + path={url path='/admin/coupon'} + request_parameter_name='coupon_order' + label="{intl l='Expiration date'}" + } + {admin_sortable_header + current_order=$coupon_order + order='days-left' + reverse_order='days-left-reverse' + path={url path='/admin/coupon'} + request_parameter_name='coupon_order' + label="{intl l='Days before expiration'}" + } + {admin_sortable_header + current_order=$coupon_order + order='usages-left' + reverse_order='usages-left-reverse' + path={url path='/admin/coupon'} + request_parameter_name='coupon_order' + label="{intl l='Usages left'}" + } +  
    {block name="coupon-code"}{$CODE}{/block}{block name="coupon-title"}{$TITLE}{/block}{block name="coupon-expiration-date"}{$EXPIRATION_DATE}{/block} - {block name="coupon-usage-left"} - {if $USAGE_LEFT == -1} - - {intl l="Unlimited"} - - {elseif $USAGE_LEFT} - - {$USAGE_LEFT} - - {else} - - 0 - - {/if} - {/block} + {loop type="auth" name="can_change" role="ADMIN" resource="admin.coupon" access="UPDATE"} + {$CODE} + {/loop} + {elseloop rel="can_change"} + {$CODE} + {/elseloop} - {block name="coupon-action"} - - {intl l='Edit'} - - {/block} + + {$TITLE} + {if $IS_ENABLED} + {intl l="Enabled"} + {else} + {intl l="Disabled"} + {/if} + {format_date date=$EXPIRATION_DATE output="date"} + {if $DAY_LEFT_BEFORE_EXPIRATION <= 0} + {intl l='Expired'} + {else} + {$DAY_LEFT_BEFORE_EXPIRATION} + {/if} + + {if $USAGE_LEFT == -1} + {intl l="Unlimited"} + {elseif $USAGE_LEFT} + {$USAGE_LEFT} + {else} + 0 + {/if} + + {loop type="auth" name="can_change" role="ADMIN" resource="admin.coupon" access="UPDATE"} + + {/loop}
    + + {module_include location='coupon_bottom'} +
    From aacdde502401e55a77787946bebf89d0ac6d15eb Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Thu, 1 May 2014 19:22:15 +0200 Subject: [PATCH 16/48] Added close button --- templates/backOffice/default/coupon/form.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/backOffice/default/coupon/form.html b/templates/backOffice/default/coupon/form.html index f6d4365c0..34432ae1e 100644 --- a/templates/backOffice/default/coupon/form.html +++ b/templates/backOffice/default/coupon/form.html @@ -28,7 +28,8 @@ file = "includes/inner-form-toolbar.html" hide_submit_buttons = false - page_url = "{url path="{$formAction}"}" + page_url = {url path=$formAction} + close_url = {url path='/admin/coupon'} } {/if} From d8c100373b065106c5af456671b176d65d51edd2 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 12:05:32 +0200 Subject: [PATCH 17/48] Using template for coupons HTML fragments --- .../backOffice/default/assets/js/coupon.js | 29 +-- .../backOffice/default/coupon-create.html | 7 +- .../backOffice/default/coupon-update.html | 5 +- .../backOffice/default/coupon/conditions.html | 14 +- templates/backOffice/default/coupon/form.html | 212 +++++++++--------- 5 files changed, 133 insertions(+), 134 deletions(-) diff --git a/templates/backOffice/default/assets/js/coupon.js b/templates/backOffice/default/assets/js/coupon.js index 0bf95b41a..de83da5be 100644 --- a/templates/backOffice/default/assets/js/coupon.js +++ b/templates/backOffice/default/assets/js/coupon.js @@ -4,7 +4,7 @@ $(function($){ $.couponManager = {}; // Condition being updated category id - $.couponManager.conditionToUpdateServiceId = -1; + $.couponManager.conditionToUpdateServiceId = ''; // Condition being updated index $.couponManager.conditionToUpdateIndex = false; @@ -20,6 +20,7 @@ $(function($){ $.couponManager.intlPleaseRetry = ''; $.couponManager.intlPleaseSelectAnotherCondition = ''; $.couponManager.intlDoYouReallyWantToSetCouponAvailableForEveryOne = ''; + $.couponManager.intlDoYouReallyWantToDeleteThisCondition = ''; // ***************************************** // ****************** Delete *************** @@ -28,11 +29,13 @@ $(function($){ $.couponManager.onClickDeleteCondition = function() { $('.condition-delete-btn').on('click', function (e) { e.preventDefault(); - var $this = $(this); - var index = $this.attr('data-conditionIndex'); - $.couponManager.conditionToUpdateServiceId = -1; - $.couponManager.conditionToUpdateIndex = false; - $.couponManager.removeConditionAjax(index); + if (confirm($.couponManager.intlDoYouReallyWantToDeleteThisCondition)) { + var $this = $(this); + var index = $this.data('condition-index'); + $.couponManager.conditionToUpdateServiceId = ''; + $.couponManager.conditionToUpdateIndex = false; + $.couponManager.removeConditionAjax(index); + } }); }; $.couponManager.onClickDeleteCondition(); @@ -94,7 +97,7 @@ $(function($){ $('#condition-add-operators-values').html(''); // Set the condition selector to default $("#category-condition option").filter(function() { - return $(this).val() == '-1'; + return $(this).val() == ''; }).prop('selected', true); }).fail(function() { $('#condition-add-operators-values').html( @@ -115,8 +118,8 @@ $(function($){ $('.condition-update-btn').on('click', function (e) { e.preventDefault(); var $this = $(this); - $.couponManager.conditionToUpdateServiceId = $this.attr('data-serviceId'); - $.couponManager.conditionToUpdateIndex = $this.attr('data-conditionIndex'); + $.couponManager.conditionToUpdateServiceId = $this.data('service-id'); + $.couponManager.conditionToUpdateIndex = $this.data('condition-index'); $.couponManager.updateConditionSelectFromConditionInterfaceAjax( $.couponManager.conditionToUpdateIndex, @@ -135,7 +138,7 @@ $(function($){ var $this = $(this); var mainDiv = $('#condition-add-type'); var optionSelected = $('option:selected', this); - mainDiv.find('.typeToolTip').html(optionSelected.attr('data-description')); + mainDiv.find('.typeToolTip').html(optionSelected.data('description')); // Only if add mode if (false != $.couponManager.conditionToUpdateIndex) { @@ -179,7 +182,7 @@ $(function($){ } }).done(function(data) { $('#condition-add-operators-values').html(data); - if ($.couponManager.conditionToUpdateServiceId == -1) { + if ($.couponManager.conditionToUpdateServiceId == '') { // Placeholder can't be saved $('#condition-save-btn').hide(); } else { @@ -213,7 +216,7 @@ $(function($){ $.couponManager.onEffectChange = function() { var mainDiv = $('#coupon-type'); var optionSelected = mainDiv.find('#type option:selected'); - mainDiv.find('.typeToolTip').html(optionSelected.attr('data-description')); + mainDiv.find('.typeToolTip').html(optionSelected.data('description')); mainDiv.find('#type').on('change', function () { var optionSelected = $('option:selected', this); @@ -225,7 +228,7 @@ $(function($){ $.couponManager.displayEfffect = function(optionSelected) { var mainDiv = $('#coupon-type'); - mainDiv.find('.typeToolTip').html(optionSelected.attr('data-description')); + mainDiv.find('.typeToolTip').html(optionSelected.data('description')); var inputsDiv = mainDiv.find('.inputs'); inputsDiv.html('
    '); diff --git a/templates/backOffice/default/coupon-create.html b/templates/backOffice/default/coupon-create.html index 8dab9585e..b57547415 100644 --- a/templates/backOffice/default/coupon-create.html +++ b/templates/backOffice/default/coupon-create.html @@ -17,12 +17,8 @@ - - {form name="thelia.admin.coupon.creation"} - {include file='coupon/form.html' formAction={url path={$formAction}} noConditions=true} + {include file='coupon/form.html' formAction={url path={$formAction}} noConditions=true title={intl l='Create a new coupon'}} {/form} @@ -48,6 +44,7 @@ $.couponManager.urlAjaxAdminCouponDrawInputs = "{$urlAjaxAdminCouponDrawInputs}"; $.couponManager.intlPleaseRetry = '{intl l='Please retry'}'; $.couponManager.intlDoYouReallyWantToSetCouponAvailableForEveryOne = '{intl l='Do you really want to set this coupon available to everyone ?'}'; + $.couponManager.intlDoYouReallyWantToDeleteThisCondition = '{intl l='Do you really want to delete this condition ?'}'; }); diff --git a/templates/backOffice/default/coupon-update.html b/templates/backOffice/default/coupon-update.html index 9a70d6fa0..6a943027c 100644 --- a/templates/backOffice/default/coupon-update.html +++ b/templates/backOffice/default/coupon-update.html @@ -14,12 +14,12 @@
  • {intl l='Home'}
  • {intl l='Tools'}
  • {intl l='Coupon'}
  • -
  • {intl l="Editing %title" title="$couponCode"}
  • +
  • {intl l='Editing coupon "%title"' title="$couponCode"}
  • {form name="thelia.admin.coupon.creation"} - {include file='coupon/form.html' formAction={url path={$formAction}} form=$form noConditions=false} + {include file='coupon/form.html' formAction={url path={$formAction}} form=$form noConditions=false title={intl l='Editing coupon "%title"' title=$couponCode}} {/form} @@ -52,6 +52,7 @@ $.couponManager.intlPleaseRetry = '{intl l='Please retry'}'; $.couponManager.intlPleaseSelectAnotherCondition = '{intl l='Please select another condition'}'; $.couponManager.intlDoYouReallyWantToSetCouponAvailableForEveryOne = '{intl l='Do you really want to set this coupon available to everyone ?'}'; + $.couponManager.intlDoYouReallyWantToDeleteThisCondition = '{intl l='Do you really want to delete this condition ?'}'; $('#condition-save-btn').hide(); }); diff --git a/templates/backOffice/default/coupon/conditions.html b/templates/backOffice/default/coupon/conditions.html index 1ae577e42..5972c0327 100644 --- a/templates/backOffice/default/coupon/conditions.html +++ b/templates/backOffice/default/coupon/conditions.html @@ -1,5 +1,5 @@ {* List all condition with their summary *} -{foreach from=$conditions item=condition key=i name=conditionsForeach} +{foreach from=$conditions item=condition name=conditionsForeach} {if !$smarty.foreach.conditionsForeach.first} @@ -7,13 +7,15 @@ {/if} {$condition.summary nofilter} - - - {intl l='Edit'} + + + + + {if $conditions|count != 1} - - {intl l='Delete'} + + {/if} diff --git a/templates/backOffice/default/coupon/form.html b/templates/backOffice/default/coupon/form.html index 34432ae1e..a90b0df12 100644 --- a/templates/backOffice/default/coupon/form.html +++ b/templates/backOffice/default/coupon/form.html @@ -3,9 +3,10 @@
    +
    -
    - {intl l='Edit %title' title={$couponCode}} +
    + {$title}
    @@ -34,19 +35,12 @@ {/if}
    -
    +
    {form_field form=$form field='code'}
    - + - {if $error}{$message}{/if} -
    - {/form_field} - - {form_field form=$form field='title'} -
    - - + {intl l='This is the code entered by your customers to use this coupon'} {if $error}{$message}{/if}
    {/form_field} @@ -56,7 +50,7 @@
    {/form_field} @@ -66,7 +60,7 @@
    {/form_field} @@ -76,7 +70,7 @@
    {/form_field} @@ -86,7 +80,7 @@
    {/form_field} @@ -107,125 +101,127 @@ - - + + {if $error}{$message}{/if}
    {/form_field}
    -
    -
    -
    - {form_field form=$form field='type'} -
    - - - {if $error}{$message}{/if} - {$availableCoupons.0.toolTip} -
    - {/form_field} -
    +
    -
    +
    + {form_field form=$form field='type'} +
    + + + {if $error}{$message}{/if} + {$availableCoupons.0.toolTip} +
    + {/form_field} + +
    {form_field form=$form field='amount'} - {$couponInputsHtml nofilter} + {$couponInputsHtml nofilter} {/form_field}
    +
    + +
    + + {form_field form=$form field='title'} +
    + + + {if $error}{$message}{/if} +
    + {/form_field} {form_field form=$form field='shortDescription'}
    - + {if $error}{$message}{/if}
    {/form_field} -
    - -
    -
    {form_field form=$form field='description'}
    - + {if $error}{$message}{/if}
    {/form_field} - - {if $noConditions} - - {/if}
    -
    - -
    -
    - - -{if $noConditions} - {include file='includes/notifications.html' message={intl l='Please save your Coupon in oder to affect it some conditions'}} -{else} -
    -
    - -
    - - - - - - - - - - {include file='coupon/conditions.html' conditions=$conditions} - -
    - {intl l='Conditions'} -
    {intl l='Conditions'}{intl l='Actions'}
    -
    - -
    -
    - -
    -
    - -
    -
    -
    - - {intl l='Save this condition'} - - -
    - - - -
    - -
    -
    +
    -
    - -{/if} +
    +
    + {intl l='Coupon conditions'} +
    +
    + +
    + {if $noConditions} +
    +
    + {include file='includes/notifications.html' type='info' dismissable=false message={intl l='Please save this coupon first to define coupon conditions'}} +
    + {else} +
    +
    + + + + + + + + + {include file='coupon/conditions.html' conditions=$conditions} + +
    {intl l='Condition description'}{intl l='Actions'}
    +
    +
    + +
    +
    + +
    + + + +
    + +
    + +
    + + + {intl l='Save this condition'} + + +
    +
    + {/if} +
    + + \ No newline at end of file From bbe7634ad47a5aa245eb708d42356404bb52c1f3 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 12:06:21 +0200 Subject: [PATCH 18/48] Using templates for conditions HTML fragments --- core/lib/Thelia/Coupon/BaseFacade.php | 22 +++++++++++++++++++ core/lib/Thelia/Coupon/FacadeInterface.php | 7 ++++++ core/lib/Thelia/Coupon/Type/RemoveXAmount.php | 6 ++--- .../lib/Thelia/Coupon/Type/RemoveXPercent.php | 4 ++-- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/core/lib/Thelia/Coupon/BaseFacade.php b/core/lib/Thelia/Coupon/BaseFacade.php index b137fb7ab..bdc87261d 100644 --- a/core/lib/Thelia/Coupon/BaseFacade.php +++ b/core/lib/Thelia/Coupon/BaseFacade.php @@ -18,6 +18,8 @@ use Symfony\Component\Translation\Translator; use Symfony\Component\Translation\TranslatorInterface; use Thelia\Condition\ConditionEvaluator; use Thelia\Core\HttpFoundation\Request; +use Thelia\Core\Template\ParserInterface; +use Thelia\Core\Template\TemplateHelper; use Thelia\Model\Coupon; use Thelia\Model\CouponQuery; use Thelia\Cart\CartTrait; @@ -43,6 +45,9 @@ class BaseFacade implements FacadeInterface /** @var Translator Service Translator */ protected $translator = null; + /** @var ParserInterface The thelia parser */ + private $parser = null; + /** * Constructor * @@ -197,6 +202,23 @@ class BaseFacade implements FacadeInterface return $this->container->get('thelia.translator'); } + /** + * Return platform Parser + * + * @return ParserInterface + */ + public function getParser() + { + if ($this->parser == null) { + $this->parser = $this->container->get('thelia.parser'); + + // Define the current back-office template that should be used + $this->parser->setTemplateDefinition(TemplateHelper::getInstance()->getActiveAdminTemplate()); + } + + return $this->parser; + } + /** * Return the main currency * THe one used to set prices in BackOffice diff --git a/core/lib/Thelia/Coupon/FacadeInterface.php b/core/lib/Thelia/Coupon/FacadeInterface.php index 35b0c3891..40e4e2948 100644 --- a/core/lib/Thelia/Coupon/FacadeInterface.php +++ b/core/lib/Thelia/Coupon/FacadeInterface.php @@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Translation\TranslatorInterface; use Thelia\Condition\ConditionEvaluator; use Thelia\Core\HttpFoundation\Request; +use Thelia\Core\Template\ParserInterface; use Thelia\Model\Coupon; /** @@ -129,6 +130,12 @@ interface FacadeInterface * @return TranslatorInterface */ public function getTranslator(); + /** + * Return platform ParserInterface + * + * @return ParserInterface + */ + public function getParser(); /** * Return the main currency diff --git a/core/lib/Thelia/Coupon/Type/RemoveXAmount.php b/core/lib/Thelia/Coupon/Type/RemoveXAmount.php index d8d473963..5ee212b27 100644 --- a/core/lib/Thelia/Coupon/Type/RemoveXAmount.php +++ b/core/lib/Thelia/Coupon/Type/RemoveXAmount.php @@ -33,7 +33,7 @@ class RemoveXAmount extends CouponAbstract { return $this->facade ->getTranslator() - ->trans('Remove X amount to total cart', array(), 'coupon'); + ->trans('Fixed Amount Discount', array(), 'coupon'); } /** @@ -45,7 +45,7 @@ class RemoveXAmount extends CouponAbstract { return $this->facade ->getTranslator() - ->trans('Amount removed from the cart', array(), 'coupon'); + ->trans('Discount amount', array(), 'coupon'); } /** @@ -58,7 +58,7 @@ class RemoveXAmount extends CouponAbstract $toolTip = $this->facade ->getTranslator() ->trans( - 'This coupon will remove the entered amount to the customer total checkout. If the discount is superior to the total checkout price the customer will only pay the postage. Unless if the coupon is set to remove postage too.', + 'This coupon will subtracts a set amount from the total cost of an order. If the discount is greater than the total order corst, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.', array(), 'coupon' ); diff --git a/core/lib/Thelia/Coupon/Type/RemoveXPercent.php b/core/lib/Thelia/Coupon/Type/RemoveXPercent.php index 8019e564f..db0a011ea 100644 --- a/core/lib/Thelia/Coupon/Type/RemoveXPercent.php +++ b/core/lib/Thelia/Coupon/Type/RemoveXPercent.php @@ -116,7 +116,7 @@ class RemoveXPercent extends CouponAbstract { return $this->facade ->getTranslator() - ->trans('Percentage removed from the cart', array(), 'coupon'); + ->trans('Percent Discount', array(), 'coupon'); } /** @@ -129,7 +129,7 @@ class RemoveXPercent extends CouponAbstract $toolTip = $this->facade ->getTranslator() ->trans( - 'This coupon will remove the entered percentage to the customer total checkout. If the discount is superior to the total checkout price the customer will only pay the postage. Unless if the coupon is set to remove postage too.', + 'This coupon will offert a flat percentage off a shopper\'s entire order (not applied to shipping costs or tax rates). If the discount is greater than the total order corst, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.', array(), 'coupon' ); From 6b020fda1337c6f1f29a09785a8b0756f8fc1fa2 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 12:07:17 +0200 Subject: [PATCH 19/48] Fixed labels, using templates for HTML fragments --- .../Thelia/Condition/ConditionCollection.php | 4 +- .../lib/Thelia/Condition/ConditionFactory.php | 2 +- .../Implementation/ConditionAbstract.php | 121 +++++++++--------- .../Implementation/MatchForEveryone.php | 20 +-- .../Implementation/MatchForTotalAmount.php | 79 +++--------- .../Implementation/MatchForXArticles.php | 39 ++---- core/lib/Thelia/Condition/Operators.php | 34 ++--- .../Condition/SerializableCondition.php | 4 +- .../Controller/Admin/CouponController.php | 42 +++--- 9 files changed, 150 insertions(+), 195 deletions(-) diff --git a/core/lib/Thelia/Condition/ConditionCollection.php b/core/lib/Thelia/Condition/ConditionCollection.php index 7b70df07c..d820edfe1 100644 --- a/core/lib/Thelia/Condition/ConditionCollection.php +++ b/core/lib/Thelia/Condition/ConditionCollection.php @@ -27,7 +27,7 @@ use Thelia\Condition\Implementation\ConditionInterface; class ConditionCollection implements Iterator, Countable, ArrayAccess { /** @var array Array of ConditionInterface */ - protected $conditions = array(); + protected $conditions = []; /** * (PHP 5 >= 5.0.0) @@ -180,7 +180,7 @@ class ConditionCollection implements Iterator, Countable, ArrayAccess */ public function __toString() { - $arrayToSerialize = array(); + $arrayToSerialize = []; /** @var ConditionInterface $condition */ foreach ($this as $condition) { $arrayToSerialize[] = $condition->getSerializableCondition(); diff --git a/core/lib/Thelia/Condition/ConditionFactory.php b/core/lib/Thelia/Condition/ConditionFactory.php index 60e2643b9..8fd9647b6 100644 --- a/core/lib/Thelia/Condition/ConditionFactory.php +++ b/core/lib/Thelia/Condition/ConditionFactory.php @@ -61,7 +61,7 @@ class ConditionFactory ); $collection[] = $conditionNone; } - $serializableConditions = array(); + $serializableConditions = []; /** @var $condition ConditionInterface */ foreach ($collection as $condition) { $serializableConditions[] = $condition->getSerializableCondition(); diff --git a/core/lib/Thelia/Condition/Implementation/ConditionAbstract.php b/core/lib/Thelia/Condition/Implementation/ConditionAbstract.php index 5a1f5c71d..5ddf4f6e4 100644 --- a/core/lib/Thelia/Condition/Implementation/ConditionAbstract.php +++ b/core/lib/Thelia/Condition/Implementation/ConditionAbstract.php @@ -18,6 +18,7 @@ use Thelia\Condition\SerializableCondition; use Thelia\Core\Translation\Translator; use Thelia\Coupon\FacadeInterface; use Thelia\Exception\InvalidConditionValueException; +use Thelia\Model\Base\CurrencyQuery; use Thelia\Model\Currency; use Thelia\Type\FloatType; @@ -35,10 +36,10 @@ abstract class ConditionAbstract implements ConditionInterface protected $serviceId = null; /** @var array Available Operators (Operators::CONST) */ - protected $availableOperators = array(); + protected $availableOperators = []; /** @var array Parameters validating parameters against */ - protected $validators = array(); + protected $validators = []; /** @var FacadeInterface Provide necessary value from Thelia */ protected $facade = null; @@ -47,10 +48,10 @@ abstract class ConditionAbstract implements ConditionInterface protected $translator = null; /** @var array Operators set by Admin in BackOffice */ - protected $operators = array(); + protected $operators = []; /** @var array Values set by Admin in BackOffice */ - protected $values = array(); + protected $values = []; /** @var ConditionEvaluator Conditions validator */ protected $conditionValidator = null; @@ -64,6 +65,7 @@ abstract class ConditionAbstract implements ConditionInterface { $this->facade = $facade; $this->translator = $facade->getTranslator(); + $this->parser = $facade->getParser(); $this->conditionValidator = $facade->getConditionEvaluator(); } @@ -86,9 +88,9 @@ abstract class ConditionAbstract implements ConditionInterface { $this->validators = $this->generateInputs(); - $translatedInputs = array(); + $translatedInputs = []; foreach ($this->validators as $key => $validator) { - $translatedOperators = array(); + $translatedOperators = []; foreach ($validator['availableOperators'] as $availableOperators) { $translatedOperators[$availableOperators] = Operators::getI18n( $this->translator, @@ -99,7 +101,7 @@ abstract class ConditionAbstract implements ConditionInterface $validator['availableOperators'] = $translatedOperators; $translatedInputs[$key] = $validator; } - $validators = array(); + $validators = []; $validators['inputs'] = $translatedInputs; $validators['setOperators'] = $this->operators; $validators['setValues'] = $this->values; @@ -216,27 +218,21 @@ abstract class ConditionAbstract implements ConditionInterface */ protected function drawBackOfficeInputOperators($inputKey) { - $selectHtml = ''; - $optionHtml = ''; - $inputs = $this->getValidators(); - if (isset($inputs['inputs'][$inputKey])) { - $operators = $inputs['inputs'][$inputKey]['availableOperators']; - foreach ($operators as $key => $operator) { - $selected = ''; - if (isset($this->operators) && isset($this->operators[$inputKey]) && $this->operators[$inputKey] == $key) { - $selected = ' selected="selected"'; - } - $optionHtml .= ''; - } + $html = ''; - $selectHtml .= ' - - '; + $inputs = $this->getValidators(); + + if (isset($inputs['inputs'][$inputKey])) { + + $html = $this->facade->getParser()->render('coupon/condition-fragments/condition-selector.html', [ + 'operators' => $inputs['inputs'][$inputKey]['availableOperators'], + 'value' => isset($this->operators[$inputKey]) ? $this->operators[$inputKey] : '', + 'inputKey' => $inputKey + ] + ); } - return $selectHtml; + return $html; } /** @@ -251,26 +247,19 @@ abstract class ConditionAbstract implements ConditionInterface protected function drawBackOfficeBaseInputsText($label, $inputKey) { $operatorSelectHtml = $this->drawBackOfficeInputOperators($inputKey); + $currentValue = ''; if (isset($this->values) && isset($this->values[$inputKey])) { $currentValue = $this->values[$inputKey]; } - $html = ' -
    - -
    -
    - ' . $operatorSelectHtml . ' -
    -
    - -
    -
    -
    - '; - - return $html; + return $this->facade->getParser()->render('coupon/conditions-fragments/base-input-text.html', [ + 'label' => $label, + 'inputKey' => $inputKey, + 'currentValue' => $currentValue, + 'operatorSelectHtml' => $operatorSelectHtml + ] + ); } /** @@ -285,23 +274,39 @@ abstract class ConditionAbstract implements ConditionInterface */ protected function drawBackOfficeInputQuantityValues($inputKey, $max = 10, $min = 0) { - $selectHtml = ''; - $optionHtml = ''; - for ($i = $min; $i <= $max; $i++) { - $selected = ''; - if (isset($this->values) && isset($this->values[$inputKey]) && $this->values[$inputKey] == $i) { - $selected = ' selected="selected"'; - } - $optionHtml .= ''; - } - - $selectHtml .= ' - - '; - - return $selectHtml; + return $this->facade->getParser()->render('coupon/condition-fragments/quantity-selector.html', [ + 'min' => $min, + 'max' => $max, + 'value' => isset($this->values[$inputKey]) ? $this->values[$inputKey] : '', + 'inputKey' => $inputKey + ] + ); } -} + /** + * Draw the currency input displayed in the BackOffice + * allowing Admin to set its Coupon Conditions + * + * @param string $inputKey Input key (ex: self::INPUT1) + * + * @return string HTML string + */ + protected function drawBackOfficeCurrencyInput($inputKey) + { + $currencies = CurrencyQuery::create()->find(); + + $cleanedCurrencies = []; + + /** @var Currency $currency */ + foreach ($currencies as $currency) { + $cleanedCurrencies[$currency->getCode()] = $currency->getSymbol(); + } + + return $this->facade->getParser()->render('coupon/condition-fragments/currency-selector.html', [ + 'currencies' => $cleanedCurrencies, + 'value' => isset($this->values[$inputKey]) ? $this->values[$inputKey] : '', + 'inputKey' => $inputKey + ] + ); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Condition/Implementation/MatchForEveryone.php b/core/lib/Thelia/Condition/Implementation/MatchForEveryone.php index a5a3e4d1d..5049470a2 100644 --- a/core/lib/Thelia/Condition/Implementation/MatchForEveryone.php +++ b/core/lib/Thelia/Condition/Implementation/MatchForEveryone.php @@ -25,7 +25,7 @@ class MatchForEveryone extends ConditionAbstract protected $serviceId = 'thelia.condition.match_for_everyone'; /** @var array Available Operators (Operators::CONST) */ - protected $availableOperators = array(); + protected $availableOperators = []; /** * Check validators relevancy and store them @@ -51,8 +51,8 @@ class MatchForEveryone extends ConditionAbstract */ protected function setValidators() { - $this->operators = array(); - $this->values = array(); + $this->operators = []; + $this->values = []; return $this; } @@ -75,8 +75,8 @@ class MatchForEveryone extends ConditionAbstract public function getName() { return $this->translator->trans( - 'Everybody can use it (no condition)', - array(), + 'Unconditional usage', + [], 'condition' ); } @@ -90,8 +90,8 @@ class MatchForEveryone extends ConditionAbstract public function getToolTip() { $toolTip = $this->translator->trans( - 'Will return always true', - array(), + 'This condition is always true', + [], 'condition' ); @@ -107,8 +107,8 @@ class MatchForEveryone extends ConditionAbstract public function getSummary() { $toolTip = $this->translator->trans( - 'Will return always true', - array(), + 'Unconditionnal usage', + [], 'condition' ); @@ -122,7 +122,7 @@ class MatchForEveryone extends ConditionAbstract */ protected function generateInputs() { - return array(); + return []; } /** diff --git a/core/lib/Thelia/Condition/Implementation/MatchForTotalAmount.php b/core/lib/Thelia/Condition/Implementation/MatchForTotalAmount.php index 5c26ee75b..6b4b48f15 100644 --- a/core/lib/Thelia/Condition/Implementation/MatchForTotalAmount.php +++ b/core/lib/Thelia/Condition/Implementation/MatchForTotalAmount.php @@ -153,7 +153,7 @@ class MatchForTotalAmount extends ConditionAbstract { return $this->translator->trans( 'By cart total amount', - array(), + [], 'condition' ); } @@ -168,7 +168,7 @@ class MatchForTotalAmount extends ConditionAbstract { $toolTip = $this->translator->trans( 'Check the total Cart amount in the given currency', - array(), + [], 'condition' ); @@ -208,7 +208,7 @@ class MatchForTotalAmount extends ConditionAbstract protected function generateInputs() { $currencies = CurrencyQuery::create()->find(); - $cleanedCurrencies = array(); + $cleanedCurrencies = []; /** @var Currency $currency */ foreach ($currencies as $currency) { $cleanedCurrencies[$currency->getCode()] = $currency->getSymbol(); @@ -240,7 +240,7 @@ class MatchForTotalAmount extends ConditionAbstract { $labelPrice = $this->facade ->getTranslator() - ->trans('Price', array(), 'condition'); + ->trans('Cart total amount is', [], 'condition'); $html = $this->drawBackOfficeBaseInputsText($labelPrice, self::INPUT1); @@ -258,66 +258,17 @@ class MatchForTotalAmount extends ConditionAbstract */ protected function drawBackOfficeBaseInputsText($label, $inputKey) { - $operatorSelectHtml = $this->drawBackOfficeInputOperators(self::INPUT1); - $currencySelectHtml = $this->drawBackOfficeCurrencyInput(self::INPUT2); - $selectedAmount = ''; - if (isset($this->values) && isset($this->values[$inputKey])) { - $selectedAmount = $this->values[$inputKey]; - } + return $this->facade->getParser()->render('coupon/condition-fragments/cart-total-amount-condition.html', [ + 'label' => $label, + 'inputKey' => $inputKey, + 'value' => isset($this->values[$inputKey]) ? $this->values[$inputKey] : '', - $html = ' - -
    -
    - ' . $operatorSelectHtml . ' -
    -
    - -
    -
    - - ' . $currencySelectHtml . ' -
    -
    - '; + 'field_1_name' => self::INPUT1, + 'field_2_name' => self::INPUT2, - return $html; + 'operatorSelectHtml' => $this->drawBackOfficeInputOperators(self::INPUT1), + 'currencySelectHtml' => $this->drawBackOfficeCurrencyInput(self::INPUT2), + ] + ); } - - /** - * Draw the currency input displayed in the BackOffice - * allowing Admin to set its Coupon Conditions - * - * @param string $inputKey Input key (ex: self::INPUT1) - * - * @return string HTML string - */ - protected function drawBackOfficeCurrencyInput($inputKey) - { - $optionHtml = ''; - - $currencies = CurrencyQuery::create()->find(); - $cleanedCurrencies = array(); - /** @var Currency $currency */ - foreach ($currencies as $currency) { - $cleanedCurrencies[$currency->getCode()] = $currency->getSymbol(); - } - - foreach ($cleanedCurrencies as $key => $cleanedCurrency) { - $selected = ''; - if (isset($this->values) && isset($this->values[$inputKey]) && $this->values[$inputKey] == $key) { - $selected = ' selected="selected"'; - } - $optionHtml .= ''; - } - - $selectHtml = ' - - '; - - return $selectHtml; - } - -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Condition/Implementation/MatchForXArticles.php b/core/lib/Thelia/Condition/Implementation/MatchForXArticles.php index dec3fff29..0e7c9d832 100644 --- a/core/lib/Thelia/Condition/Implementation/MatchForXArticles.php +++ b/core/lib/Thelia/Condition/Implementation/MatchForXArticles.php @@ -127,8 +127,8 @@ class MatchForXArticles extends ConditionAbstract public function getName() { return $this->translator->trans( - 'By number of articles in cart', - array(), + 'Cart item count condition', + [], 'condition' ); } @@ -142,8 +142,8 @@ class MatchForXArticles extends ConditionAbstract public function getToolTip() { $toolTip = $this->translator->trans( - 'Check the amount of product in the Cart', - array(), + 'The cart item count should match the condition', + [], 'condition' ); @@ -163,7 +163,7 @@ class MatchForXArticles extends ConditionAbstract ); $toolTip = $this->translator->trans( - 'If cart products quantity is %operator% %quantity%', + 'If cart item count is %operator% %quantity%', array( '%operator%' => $i18nOperator, '%quantity%' => $this->values[self::INPUT1] @@ -200,7 +200,7 @@ class MatchForXArticles extends ConditionAbstract { $labelQuantity = $this->facade ->getTranslator() - ->trans('Quantity', array(), 'condition'); + ->trans('Cart item count is', [], 'condition'); $html = $this->drawBackOfficeBaseInputsText($labelQuantity, self::INPUT1); @@ -218,24 +218,11 @@ class MatchForXArticles extends ConditionAbstract */ protected function drawBackOfficeBaseInputsText($label, $inputKey) { - $operatorSelectHtml = $this->drawBackOfficeInputOperators($inputKey); - $quantitySelectHtml = $this->drawBackOfficeInputQuantityValues($inputKey, 20, 1); - - $html = ' -
    - -
    -
    - ' . $operatorSelectHtml . ' -
    -
    - ' . $quantitySelectHtml . ' -
    -
    -
    - '; - - return $html; + return $this->facade->getParser()->render('coupon/condition-fragments/cart-item-count-condition.html', [ + 'label' => $label, + 'operatorSelectHtml' => $this->drawBackOfficeInputOperators($inputKey), + 'quantitySelectHtml' => $this->drawBackOfficeInputQuantityValues($inputKey, 20, 1) + ] + ); } - -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Condition/Operators.php b/core/lib/Thelia/Condition/Operators.php index 5d1801839..7d2ae1485 100644 --- a/core/lib/Thelia/Condition/Operators.php +++ b/core/lib/Thelia/Condition/Operators.php @@ -54,57 +54,57 @@ abstract class Operators switch ($operator) { case self::INFERIOR: $ret = $translator->trans( - 'inferior to', - array(), + 'Less than', + [], 'condition' ); break; case self::INFERIOR_OR_EQUAL: $ret = $translator->trans( - 'inferior or equal to', - array(), + 'Less than or equals', + [], 'condition' ); break; case self::EQUAL: $ret = $translator->trans( - 'equal to', - array(), + 'Equals to', + [], 'condition' ); break; case self::SUPERIOR_OR_EQUAL: $ret = $translator->trans( - 'superior or equal to', - array(), + 'Greater than or equals', + [], 'condition' ); break; case self::SUPERIOR: $ret = $translator->trans( - 'superior to', - array(), + 'Greater than', + [], 'condition' ); break; case self::DIFFERENT: $ret = $translator->trans( - 'different from', - array(), + 'Not equals', + [], 'condition' ); break; case self::IN: $ret = $translator->trans( - 'in', - array(), + 'In', + [], 'condition' ); break; case self::OUT: $ret = $translator->trans( - 'not in', - array(), + 'Not in', + [], 'condition' ); break; @@ -113,4 +113,4 @@ abstract class Operators return $ret; } -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Condition/SerializableCondition.php b/core/lib/Thelia/Condition/SerializableCondition.php index 0e921388f..8d8cf4a7d 100644 --- a/core/lib/Thelia/Condition/SerializableCondition.php +++ b/core/lib/Thelia/Condition/SerializableCondition.php @@ -25,9 +25,9 @@ class SerializableCondition public $conditionServiceId = null; /** @var array Operators set by Admin for this Condition */ - public $operators = array(); + public $operators = []; /** @var array Values set by Admin for this Condition */ - public $values = array(); + public $values = []; } diff --git a/core/lib/Thelia/Controller/Admin/CouponController.php b/core/lib/Thelia/Controller/Admin/CouponController.php index 82c3a97d5..6ecd418e8 100644 --- a/core/lib/Thelia/Controller/Admin/CouponController.php +++ b/core/lib/Thelia/Controller/Admin/CouponController.php @@ -292,30 +292,42 @@ class CouponController extends BaseAdminController */ public function getConditionEmptyInputAjaxAction($conditionId) { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) + return $response; $this->checkXmlHttpRequest(); - /** @var ConditionFactory $conditionFactory */ - $conditionFactory = $this->container->get('thelia.condition.factory'); - $inputs = $conditionFactory->getInputsFromServiceId($conditionId); - if (!$this->container->has($conditionId)) { - return false; + if (! empty($conditionId)) { + + /** @var ConditionFactory $conditionFactory */ + $conditionFactory = $this->container->get('thelia.condition.factory'); + $inputs = $conditionFactory->getInputsFromServiceId($conditionId); + + if (!$this->container->has($conditionId)) { + return false; + } + + if ($inputs === null) { + return $this->pageNotFound(); + } + + /** @var ConditionInterface $condition */ + $condition = $this->container->get($conditionId); + + $html = $condition->drawBackOfficeInputs(); + $serviceId = $condition->getServiceId(); } - - /** @var ConditionInterface $condition */ - $condition = $this->container->get($conditionId); - - if ($inputs === null) { - return $this->pageNotFound(); + else { + $html = ''; + $serviceId = ''; } return $this->render( 'coupon/condition-input-ajax', array( - 'inputsDrawn' => $condition->drawBackOfficeInputs(), - 'conditionServiceId' => $condition->getServiceId(), - 'conditionIndex' => -1, + 'inputsDrawn' => $html, + 'conditionServiceId' => $serviceId, + 'conditionIndex' => '', ) ); } From d0528a91d2e7ad56abebd96b9a52b0d1c192e934 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 12:08:22 +0200 Subject: [PATCH 20/48] Coupons conditions HTML fragments --- .../condition-fragments/base-input-text.html | 11 ++++++++++ .../cart-item-count-condition.html | 11 ++++++++++ .../cart-total-amount-condition.html | 20 +++++++++++++++++++ .../condition-selector.html | 5 +++++ .../currency-selector.html | 5 +++++ .../quantity-selector.html | 9 +++++++++ 6 files changed, 61 insertions(+) create mode 100644 templates/backOffice/default/coupon/condition-fragments/base-input-text.html create mode 100644 templates/backOffice/default/coupon/condition-fragments/cart-item-count-condition.html create mode 100644 templates/backOffice/default/coupon/condition-fragments/cart-total-amount-condition.html create mode 100644 templates/backOffice/default/coupon/condition-fragments/condition-selector.html create mode 100644 templates/backOffice/default/coupon/condition-fragments/currency-selector.html create mode 100644 templates/backOffice/default/coupon/condition-fragments/quantity-selector.html diff --git a/templates/backOffice/default/coupon/condition-fragments/base-input-text.html b/templates/backOffice/default/coupon/condition-fragments/base-input-text.html new file mode 100644 index 000000000..422ae441a --- /dev/null +++ b/templates/backOffice/default/coupon/condition-fragments/base-input-text.html @@ -0,0 +1,11 @@ +
    + +
    +
    + {$operatorSelectHtml nofilter} +
    +
    + +
    +
    +
    \ No newline at end of file diff --git a/templates/backOffice/default/coupon/condition-fragments/cart-item-count-condition.html b/templates/backOffice/default/coupon/condition-fragments/cart-item-count-condition.html new file mode 100644 index 000000000..199fd11b8 --- /dev/null +++ b/templates/backOffice/default/coupon/condition-fragments/cart-item-count-condition.html @@ -0,0 +1,11 @@ +
    + +
    +
    + {$operatorSelectHtml nofilter} +
    +
    + {$quantitySelectHtml nofilter} +
    +
    +
    \ No newline at end of file diff --git a/templates/backOffice/default/coupon/condition-fragments/cart-total-amount-condition.html b/templates/backOffice/default/coupon/condition-fragments/cart-total-amount-condition.html new file mode 100644 index 000000000..53530f14e --- /dev/null +++ b/templates/backOffice/default/coupon/condition-fragments/cart-total-amount-condition.html @@ -0,0 +1,20 @@ +
    + + + +
    +
    + {$operatorSelectHtml nofilter} +
    + +
    + +
    + +
    + + {$currencySelectHtml nofilter} +
    +
    + +
    \ No newline at end of file diff --git a/templates/backOffice/default/coupon/condition-fragments/condition-selector.html b/templates/backOffice/default/coupon/condition-fragments/condition-selector.html new file mode 100644 index 000000000..d1df54d97 --- /dev/null +++ b/templates/backOffice/default/coupon/condition-fragments/condition-selector.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/templates/backOffice/default/coupon/condition-fragments/currency-selector.html b/templates/backOffice/default/coupon/condition-fragments/currency-selector.html new file mode 100644 index 000000000..70b39addf --- /dev/null +++ b/templates/backOffice/default/coupon/condition-fragments/currency-selector.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/templates/backOffice/default/coupon/condition-fragments/quantity-selector.html b/templates/backOffice/default/coupon/condition-fragments/quantity-selector.html new file mode 100644 index 000000000..1da60de16 --- /dev/null +++ b/templates/backOffice/default/coupon/condition-fragments/quantity-selector.html @@ -0,0 +1,9 @@ + +{* Use a text field instead + +*} + From d24d3c71bda27aebe53e3eded7a9577c9c0e8b93 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 12:23:40 +0200 Subject: [PATCH 21/48] Adding some padding to error texts --- .../backOffice/default/general_error.html | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/templates/backOffice/default/general_error.html b/templates/backOffice/default/general_error.html index 503cc4106..cefed6cb5 100644 --- a/templates/backOffice/default/general_error.html +++ b/templates/backOffice/default/general_error.html @@ -1,24 +1,24 @@ -{extends file="admin-layout.tpl"} - -{* -- We do not check admin login on this page *} -{block name="check-auth"}{/block} - -{block name="page-title"}{intl l='An error occured'}{/block} - -{block name="main-content"} -
    - -
    -
    -
    -

    {intl l="Oops! An Error Occurred"}

    - - {block name="error-message"}

    {$error_message}

    {/block} - - {intl l="Go to administration home"} -
    -
    -
    - -
    +{extends file="admin-layout.tpl"} + +{* -- We do not check admin login on this page *} +{block name="check-auth"}{/block} + +{block name="page-title"}{intl l='An error occured'}{/block} + +{block name="main-content"} +
    + +
    +
    +
    +

    {intl l="Oops! An Error Occurred"}

    + + {block name="error-message"}

    {$error_message}

    {/block} + + {intl l="Go to administration home"} +
    +
    +
    + +
    {/block} \ No newline at end of file From aa48a733437c2e375773cd2e047f2c34de67a080 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 12:24:11 +0200 Subject: [PATCH 22/48] Removed the useless coupon read function --- .../Thelia/Config/Resources/routing/admin.xml | 6 +- .../Controller/Admin/CouponController.php | 79 +++----- templates/backOffice/default/coupon-read.html | 173 ------------------ 3 files changed, 23 insertions(+), 235 deletions(-) delete mode 100644 templates/backOffice/default/coupon-read.html diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index aff2e8a5b..348c1d7ec 100644 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -512,10 +512,6 @@ Thelia\Controller\Admin\CouponController::updateAction \d+
    - - Thelia\Controller\Admin\CouponController::readAction - \d+ - Thelia\Controller\Admin\CouponController::getBackOfficeInputsAjaxAction .* @@ -549,7 +545,7 @@ - + Thelia\Controller\Admin\ConfigurationController::indexAction diff --git a/core/lib/Thelia/Controller/Admin/CouponController.php b/core/lib/Thelia/Controller/Admin/CouponController.php index 6ecd418e8..695c7c868 100644 --- a/core/lib/Thelia/Controller/Admin/CouponController.php +++ b/core/lib/Thelia/Controller/Admin/CouponController.php @@ -53,58 +53,15 @@ class CouponController extends BaseAdminController */ public function browseAction() { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); - - $args['urlReadCoupon'] = $this->getRoute( - 'admin.coupon.read', - array('couponId' => 0), - Router::ABSOLUTE_URL - ); - - $args['urlEditCoupon'] = $this->getRoute( - 'admin.coupon.update', - array('couponId' => 0), - Router::ABSOLUTE_URL - ); - - $args['urlCreateCoupon'] = $this->getRoute( - 'admin.coupon.create', - array(), - Router::ABSOLUTE_URL - ); + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) { + return $response; + } $args['coupon_order'] = $this->getListOrderFromSession('coupon', 'coupon_order', 'code'); return $this->render('coupon-list', $args); } - /** - * Manage Coupons read display - * - * @param int $couponId Coupon Id - * - * @return \Thelia\Core\HttpFoundation\Response - */ - public function readAction($couponId) - { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); - - $coupon = CouponQuery::create()->findPk($couponId); - - if ($coupon === null) { - return $this->pageNotFound(); - } - - $args['couponId'] = $couponId; - $args['urlEditCoupon'] = $this->getRoute( - 'admin.coupon.update', - array('couponId' => $couponId), - Router::ABSOLUTE_URL - ); - - return $this->render('coupon-read', $args); - } - /** * Manage Coupons creation display * @@ -112,9 +69,7 @@ class CouponController extends BaseAdminController */ public function createAction() { - // Check current user authorization - $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::CREATE); - if ($response !== null) { + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::CREATE)) { return $response; } @@ -165,9 +120,7 @@ class CouponController extends BaseAdminController */ public function updateAction($couponId) { - // Check current user authorization - $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::UPDATE); - if ($response !== null) { + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::UPDATE)) { return $response; } @@ -342,7 +295,9 @@ class CouponController extends BaseAdminController */ public function getConditionToUpdateInputAjaxAction($couponId, $conditionIndex) { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) { + return $response; + } $this->checkXmlHttpRequest(); @@ -396,7 +351,9 @@ class CouponController extends BaseAdminController */ public function saveConditionsAction($couponId) { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::UPDATE)) { + return $response; + } $this->checkXmlHttpRequest(); @@ -443,7 +400,9 @@ class CouponController extends BaseAdminController */ public function deleteConditionsAction($couponId, $conditionIndex) { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::UPDATE)) { + return $response; + } $this->checkXmlHttpRequest(); @@ -681,7 +640,10 @@ class CouponController extends BaseAdminController */ public function getBackOfficeInputsAjaxAction($couponServiceId) { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) { + return $response; + } + $this->checkXmlHttpRequest(); /** @var CouponInterface $coupon */ @@ -706,7 +668,10 @@ class CouponController extends BaseAdminController */ public function getBackOfficeConditionSummariesAjaxAction($couponId) { - $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW); + if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) { + return $response; + } + $this->checkXmlHttpRequest(); /** @var Coupon $coupon */ diff --git a/templates/backOffice/default/coupon-read.html b/templates/backOffice/default/coupon-read.html deleted file mode 100644 index 3492bd605..000000000 --- a/templates/backOffice/default/coupon-read.html +++ /dev/null @@ -1,173 +0,0 @@ -{extends file="admin-layout.tpl"} - -{block name="check-resource"}admin.coupon{/block} -{block name="check-access"}view{/block} - -{block name="page-title"}{intl l='Coupon'}{/block} - -{block name="main-content"} -
    - -
    - - {loop type="coupon" name="read_coupon" id={$couponId} backend_context="true"} - - -
    -
    -
    -
    - - {if !$IS_ENABLED} -
    - - {intl l='This coupon is disabled, you can enable at the bottom of this form.'} -
    - {/if} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {intl l='Title'}{$TITLE}
    - {if $IS_ENABLED} - - {intl l="Is enabled"} - - {else} - - {intl l="Is disabled"} - - {/if} -
    - {$SUMMARY} -
    {intl l='Amount'}{$AMOUNT}
    {intl l='Expiration date'}{$EXPIRATION_DATE} ({$DAY_LEFT_BEFORE_EXPIRATION} {intl l="days left"})
    {intl l='Usage left'} - {if $USAGE_LEFT == -1} - - {intl l="Unlimited"} - - {elseif $USAGE_LEFT} - - {$USAGE_LEFT} - - {else} - - 0 - - {/if} -
    - {if $IS_CUMULATIVE} - - {intl l="May be cumulative"} - - {else} - - {intl l="Can't be cumulative"} - - {/if} -
    - {if $IS_REMOVING_POSTAGE} - - {intl l="Will remove postage"} - - {else} - - {intl l="Won't remove postage"} - - {/if} -
    - {if $IS_AVAILABLE_ON_SPECIAL_OFFERS} - - {intl l="Will be available on special offers"} - - {else} - - {intl l="Won't be available on special offers"} - - {/if} -
    {intl l='Application field'} -
      - {foreach from=$APPLICATION_CONDITIONS item=condition name=conditionsForeach} - {if !$smarty.foreach.conditionsForeach.first} -
    • {intl l='And'}
    • - {/if} -
    • {$condition nofilter}
    • - {/foreach} -
    -
    {$SHORT_DESCRIPTION}
    {$DESCRIPTION}
    - - {intl l='Edit'} - -
    -
    -
    -
    -
    - {/loop} -
    -
    - -{include file='includes/confirmation-modal.html' id="enable" message="{intl l='Do you really want to enable this element ?'}"} - -{/block} - -{block name="javascript-initialization"} - {javascripts file='assets/js/main.js'} - - {/javascripts} - -{/block} - -{block name="javascript-last-call"} - {module_include location='coupon-read-js'} -{/block} From c457140deaba55b731f62c2a971cede214d69e9b Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 16:52:55 +0200 Subject: [PATCH 23/48] Added hide_save_buttons and hide_save_and_close_button parameters --- .../default/includes/inner-form-toolbar.html | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/templates/backOffice/default/includes/inner-form-toolbar.html b/templates/backOffice/default/includes/inner-form-toolbar.html index ed0cf3b3c..59d8acde7 100644 --- a/templates/backOffice/default/includes/inner-form-toolbar.html +++ b/templates/backOffice/default/includes/inner-form-toolbar.html @@ -4,7 +4,9 @@ A toolbar displayed in forms, to display language change flags, submit and close Parameters: - hide_flags: true / false. If true, the flags will not be visible - - hide_submit_buttons: true / false. If true, only the close button will be deplayed. + - hide_submit_buttons: true / false. If true, only the close button will be displayed. + - hide_save_buttons: true / false. If true, the "Save" button will be hidden + - hide_save_and_close_button: true / false. If true, the "Save and close" button will be hidden - show_currencies: true/false. If true, show the currency selection bar - page_url: the current page URL. Default is $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. @@ -48,8 +50,12 @@ Parameters:
    {if $hide_submit_buttons != true} - - + {if $hide_save_buttons != true} + + {/if} + {if $hide_save_and_close_button != true} + + {/if} {/if} {if ! empty($close_url)} {intl l='Close'} From 2647c62838ce6a6c0cbd07b54c6d59aed1e7ddff Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 16:53:37 +0200 Subject: [PATCH 24/48] Added standard toolbar in creation mode --- templates/backOffice/default/coupon/form.html | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/templates/backOffice/default/coupon/form.html b/templates/backOffice/default/coupon/form.html index a90b0df12..e4bd0e22e 100644 --- a/templates/backOffice/default/coupon/form.html +++ b/templates/backOffice/default/coupon/form.html @@ -26,11 +26,21 @@ {if !$noConditions} {include - file = "includes/inner-form-toolbar.html" - hide_submit_buttons = false + file = "includes/inner-form-toolbar.html" + hide_submit_buttons = false - page_url = {url path=$formAction} - close_url = {url path='/admin/coupon'} + page_url = {url path=$formAction} + close_url = {url path='/admin/coupon'} + } + {else} + {include + file = "includes/inner-form-toolbar.html" + hide_submit_buttons = false + hide_save_and_close_button = true + hide_flags = true + + page_url = {url path=$formAction} + close_url = {url path='/admin/coupon'} } {/if} @@ -88,11 +98,12 @@ {form_field form=$form field='expirationDate'}
    -
    - + +
    + {if $error}{$message}{/if} -
    +
    {/form_field} From 8ce6cdbae0e0570fc7660d3764902156c7397039 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 16:54:49 +0200 Subject: [PATCH 25/48] Fixed date input format and conversion --- .../Controller/Admin/CouponController.php | 128 +++++++----------- 1 file changed, 49 insertions(+), 79 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/CouponController.php b/core/lib/Thelia/Controller/Admin/CouponController.php index 695c7c868..724b34d23 100644 --- a/core/lib/Thelia/Controller/Admin/CouponController.php +++ b/core/lib/Thelia/Controller/Admin/CouponController.php @@ -34,6 +34,7 @@ use Thelia\Log\Tlog; use Thelia\Model\Coupon; use Thelia\Model\CouponQuery; use Thelia\Model\Lang; +use Thelia\Model\LangQuery; use Thelia\Tools\I18n; use Thelia\Tools\Rest\ResponseRest; @@ -53,7 +54,7 @@ class CouponController extends BaseAdminController */ public function browseAction() { - if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) { + if (null !== $response = $this->checkAuth(AdminResources::COUPON, [], AccessManager::VIEW)) { return $response; } @@ -69,12 +70,12 @@ class CouponController extends BaseAdminController */ public function createAction() { - if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::CREATE)) { + if (null !== $response = $this->checkAuth(AdminResources::COUPON, [], AccessManager::CREATE)) { return $response; } // Parameters given to the template - $args = array(); + $args = []; $i18n = new I18n(); /** @var Lang $lang */ @@ -92,15 +93,14 @@ class CouponController extends BaseAdminController } else { // If no input for expirationDate, now + 2 months $defaultDate = new \DateTime(); - $args['defaultDate'] = $defaultDate->modify('+2 month') - ->format('Y-m-d'); + $args['defaultDate'] = $defaultDate->modify('+2 month')->format($this->getDefaultDateFormat()); } - $args['dateFormat'] = $this->getSession()->getLang()->getDateFormat(); + $args['dateFormat'] = $this->getDefaultDateFormat(); $args['availableCoupons'] = $this->getAvailableCoupons(); $args['urlAjaxAdminCouponDrawInputs'] = $this->getRoute( 'admin.coupon.draw.inputs.ajax', - array('couponServiceId' => 'couponServiceId'), + ['couponServiceId' => 'couponServiceId'], Router::ABSOLUTE_URL ); $args['formAction'] = 'admin/coupon/create'; @@ -120,7 +120,7 @@ class CouponController extends BaseAdminController */ public function updateAction($couponId) { - if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::UPDATE)) { + if (null !== $response = $this->checkAuth(AdminResources::COUPON, [], AccessManager::UPDATE)) { return $response; } @@ -138,7 +138,7 @@ class CouponController extends BaseAdminController $couponManager = $couponFactory->buildCouponFromModel($coupon); // Parameters given to the template - $args = array(); + $args = []; $i18n = new I18n(); /** @var Lang $lang */ @@ -164,7 +164,7 @@ class CouponController extends BaseAdminController $coupon->getSerializedConditions() ); - $data = array( + $data = [ 'code' => $coupon->getCode(), 'title' => $coupon->getTitle(), 'amount' => $coupon->getAmount(), @@ -172,14 +172,14 @@ class CouponController extends BaseAdminController 'shortDescription' => $coupon->getShortDescription(), 'description' => $coupon->getDescription(), 'isEnabled' => $coupon->getIsEnabled(), - 'expirationDate' => $coupon->getExpirationDate('Y-m-d'), + 'expirationDate' => $coupon->getExpirationDate(), 'isAvailableOnSpecialOffers' => $coupon->getIsAvailableOnSpecialOffers(), 'isCumulative' => $coupon->getIsCumulative(), 'isRemovingPostage' => $coupon->getIsRemovingPostage(), 'maxUsage' => $coupon->getMaxUsage(), 'conditions' => $conditions, 'locale' => $this->getCurrentEditionLocale(), - ); + ]; $args['conditions'] = $this->cleanConditionForTemplate($conditions); @@ -194,45 +194,47 @@ class CouponController extends BaseAdminController $args['couponInputsHtml'] = $couponManager->drawBackOfficeInputs(); $args['urlAjaxAdminCouponDrawInputs'] = $this->getRoute( 'admin.coupon.draw.inputs.ajax', - array('couponServiceId' => 'couponServiceId'), + ['couponServiceId' => 'couponServiceId'], Router::ABSOLUTE_URL ); $args['availableConditions'] = $this->getAvailableConditions(); $args['urlAjaxGetConditionInputFromServiceId'] = $this->getRoute( 'admin.coupon.draw.condition.read.inputs.ajax', - array('conditionId' => 'conditionId'), + ['conditionId' => 'conditionId'], Router::ABSOLUTE_URL ); $args['urlAjaxGetConditionInputFromConditionInterface'] = $this->getRoute( 'admin.coupon.draw.condition.update.inputs.ajax', - array( + [ 'couponId' => $couponId, 'conditionIndex' => 8888888 - ), + ], Router::ABSOLUTE_URL ); $args['urlAjaxSaveConditions'] = $this->getRoute( 'admin.coupon.condition.save', - array('couponId' => $couponId), + ['couponId' => $couponId], Router::ABSOLUTE_URL ); $args['urlAjaxDeleteConditions'] = $this->getRoute( 'admin.coupon.condition.delete', - array( + [ 'couponId' => $couponId, 'conditionIndex' => 8888888 - ), + ], Router::ABSOLUTE_URL ); $args['urlAjaxGetConditionSummaries'] = $this->getRoute( 'admin.coupon.draw.condition.summaries.ajax', - array('couponId' => $couponId), + ['couponId' => $couponId], Router::ABSOLUTE_URL ); $args['formAction'] = 'admin/coupon/update/' . $couponId; + $args['dateFormat'] = $this->getDefaultDateFormat(); + return $this->render('coupon-update', $args); } @@ -245,7 +247,7 @@ class CouponController extends BaseAdminController */ public function getConditionEmptyInputAjaxAction($conditionId) { - if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) + if (null !== $response = $this->checkAuth(AdminResources::COUPON, [], AccessManager::VIEW)) return $response; $this->checkXmlHttpRequest(); @@ -277,11 +279,11 @@ class CouponController extends BaseAdminController return $this->render( 'coupon/condition-input-ajax', - array( + [ 'inputsDrawn' => $html, 'conditionServiceId' => $serviceId, 'conditionIndex' => '', - ) + ] ); } @@ -295,7 +297,7 @@ class CouponController extends BaseAdminController */ public function getConditionToUpdateInputAjaxAction($couponId, $conditionIndex) { - if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) { + if (null !== $response = $this->checkAuth(AdminResources::COUPON, [], AccessManager::VIEW)) { return $response; } @@ -332,13 +334,11 @@ class CouponController extends BaseAdminController } return $this->render( - 'coupon/condition-input-ajax', - array( + 'coupon/condition-input-ajax', [ 'inputsDrawn' => $condition->drawBackOfficeInputs(), 'conditionServiceId' => $condition->getServiceId(), 'conditionIndex' => $conditionIndex, - - ) + ] ); } @@ -351,7 +351,7 @@ class CouponController extends BaseAdminController */ public function saveConditionsAction($couponId) { - if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::UPDATE)) { + if (null !== $response = $this->checkAuth(AdminResources::COUPON, [], AccessManager::UPDATE)) { return $response; } @@ -400,7 +400,7 @@ class CouponController extends BaseAdminController */ public function deleteConditionsAction($couponId, $conditionIndex) { - if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::UPDATE)) { + if (null !== $response = $this->checkAuth(AdminResources::COUPON, [], AccessManager::UPDATE)) { return $response; } @@ -430,41 +430,6 @@ class CouponController extends BaseAdminController return new Response(); } - /** - * 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->setSerializedConditions( - new ConditionCollection( - array() - ) - ); - $couponBeingCreated->setIsCumulative($data['isCumulative']); - $couponBeingCreated->setIsRemovingPostage( - $data['isRemovingPostage'] - ); - $couponBeingCreated->setMaxUsage($data['maxUsage']); - $couponBeingCreated->setIsAvailableOnSpecialOffers( - $data['isAvailableOnSpecialOffers'] - ); - - return $couponBeingCreated; - } - /** * Log error message * @@ -567,10 +532,10 @@ class CouponController extends BaseAdminController /** @var CouponManager $couponManager */ $couponManager = $this->container->get('thelia.coupon.manager'); $availableConditions = $couponManager->getAvailableConditions(); - $cleanedConditions = array(); + $cleanedConditions = []; /** @var ConditionInterface $availableCondition */ foreach ($availableConditions as $availableCondition) { - $condition = array(); + $condition = []; $condition['serviceId'] = $availableCondition->getServiceId(); $condition['name'] = $availableCondition->getName(); $condition['toolTip'] = $availableCondition->getToolTip(); @@ -590,10 +555,10 @@ class CouponController extends BaseAdminController /** @var CouponManager $couponManager */ $couponManager = $this->container->get('thelia.coupon.manager'); $availableCoupons = $couponManager->getAvailableCoupons(); - $cleanedCoupons = array(); + $cleanedCoupons = []; /** @var CouponInterface $availableCoupon */ foreach ($availableCoupons as $availableCoupon) { - $condition = array(); + $condition = []; $condition['serviceId'] = $availableCoupon->getServiceId(); $condition['name'] = $availableCoupon->getName(); $condition['toolTip'] = $availableCoupon->getToolTip(); @@ -613,17 +578,17 @@ class CouponController extends BaseAdminController */ protected function cleanConditionForTemplate(ConditionCollection $conditions) { - $cleanedConditions = array(); + $cleanedConditions = []; /** @var $condition ConditionInterface */ foreach ($conditions as $index => $condition) { - $temp = array( + $temp = [ 'serviceId' => $condition->getServiceId(), 'index' => $index, 'name' => $condition->getName(), 'toolTip' => $condition->getToolTip(), 'summary' => $condition->getSummary(), 'validators' => $condition->getValidators() - ); + ]; $cleanedConditions[] = $temp; } @@ -640,7 +605,7 @@ class CouponController extends BaseAdminController */ public function getBackOfficeInputsAjaxAction($couponServiceId) { - if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) { + if (null !== $response = $this->checkAuth(AdminResources::COUPON, [], AccessManager::VIEW)) { return $response; } @@ -668,7 +633,7 @@ class CouponController extends BaseAdminController */ public function getBackOfficeConditionSummariesAjaxAction($couponId) { - if (null !== $response = $this->checkAuth(AdminResources::COUPON, array(), AccessManager::VIEW)) { + if (null !== $response = $this->checkAuth(AdminResources::COUPON, [], AccessManager::VIEW)) { return $response; } @@ -689,7 +654,7 @@ class CouponController extends BaseAdminController return $this->pageNotFound(); } - $args = array(); + $args = []; $args['conditions'] = $this->cleanConditionForTemplate($couponManager->getConditions()); return $this->render('coupon/conditions', $args); @@ -740,7 +705,7 @@ class CouponController extends BaseAdminController $serviceId = $data['type']; /** @var CouponInterface $couponManager */ $couponManager = $this->container->get($serviceId); - $effects = array(CouponAbstract::INPUT_AMOUNT_NAME => $data[CouponAbstract::INPUT_AMOUNT_NAME]); + $effects = [CouponAbstract::INPUT_AMOUNT_NAME => $data[CouponAbstract::INPUT_AMOUNT_NAME]]; $effects = $this->addExtendedLogic($effects, $couponManager->getExtendedInputs()); $couponEvent = new CouponCreateOrUpdateEvent( @@ -751,7 +716,7 @@ class CouponController extends BaseAdminController $data['shortDescription'], $data['description'], $data['isEnabled'], - \DateTime::createFromFormat('Y-m-d', $data['expirationDate']), + $data['expirationDate'], $data['isAvailableOnSpecialOffers'], $data['isCumulative'], $data['isRemovingPostage'], @@ -777,8 +742,8 @@ class CouponController extends BaseAdminController $request = $this->getRequest(); $post = $request->request->getIterator(); $serviceId = $request->request->get('categoryCondition'); - $operators = array(); - $values = array(); + $operators = []; + $values = []; foreach ($post as $key => $input) { if (isset($input['operator']) && isset($input['value'])) { $operators[$key] = $input['operator']; @@ -835,4 +800,9 @@ class CouponController extends BaseAdminController ) ); } + + protected function getDefaultDateFormat() + { + return LangQuery::create()->findOneByByDefault(true)->getDateFormat(); + } } From 989a44591f943d002d82cdfa014346ebe12dbe79 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 16:55:39 +0200 Subject: [PATCH 26/48] Added date translator --- core/lib/Thelia/Form/CouponCreationForm.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/core/lib/Thelia/Form/CouponCreationForm.php b/core/lib/Thelia/Form/CouponCreationForm.php index 2e800a882..05acf2c4e 100644 --- a/core/lib/Thelia/Form/CouponCreationForm.php +++ b/core/lib/Thelia/Form/CouponCreationForm.php @@ -16,6 +16,7 @@ use Symfony\Component\Validator\Constraints\Date; use Symfony\Component\Validator\Constraints\GreaterThanOrEqual; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotEqualTo; +use Thelia\Coupon\ExpirationDateTransformer; /** * Allow to build a form Coupon @@ -90,14 +91,16 @@ class CouponCreationForm extends BaseForm array() ) ->add( - 'expirationDate', - 'text', - array( - 'constraints' => array( - new NotBlank(), - new Date() + $this->formBuilder->create( + 'expirationDate', + 'text', + array( + 'constraints' => array( + new NotBlank(), + //new Date() + ) ) - ) + )->addViewTransformer(new ExpirationDateTransformer()) ) ->add( 'isCumulative', From 9d3dd8687af17e4ca2049996bf4cca8a2b8c6b56 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 17:07:06 +0200 Subject: [PATCH 27/48] Added the transformer --- .../Coupon/ExpirationDateTransformer.php | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 core/lib/Thelia/Coupon/ExpirationDateTransformer.php diff --git a/core/lib/Thelia/Coupon/ExpirationDateTransformer.php b/core/lib/Thelia/Coupon/ExpirationDateTransformer.php new file mode 100644 index 000000000..f63d8ebdd --- /dev/null +++ b/core/lib/Thelia/Coupon/ExpirationDateTransformer.php @@ -0,0 +1,105 @@ + + * + * Creation date: 02/05/14 15:20 + */ +class ExpirationDateTransformer implements DataTransformerInterface +{ + + /** + * Transforms a value from the original representation to a transformed representation. + * + * This method is called on two occasions inside a form field: + * + * 1. When the form field is initialized with the data attached from the datasource (object or array). + * 2. When data from a request is bound using {@link Form::bind()} to transform the new input data + * back into the renderable format. For example if you have a date field and bind '2009-10-10' onto + * it you might accept this value because its easily parsed, but the transformer still writes back + * "2009/10/10" onto the form field (for further displaying or other purposes). + * + * This method must be able to deal with empty values. Usually this will + * be NULL, but depending on your implementation other empty values are + * possible as well (such as empty strings). The reasoning behind this is + * that value transformers must be chainable. If the transform() method + * of the first value transformer outputs NULL, the second value transformer + * must be able to process that value. + * + * By convention, transform() should return an empty string if NULL is + * passed. + * + * @param mixed $value The value in the original representation + * + * @return mixed The value in the transformed representation + * + * @throws TransformationFailedException When the transformation fails. + */ + public function transform($value) + { + if (empty($value)) return ''; + + // Get the default language + $lang = LangQuery::create()->findOneByByDefault(1); + + if (false !== $dt = \DateTime::createFromFormat($lang->getDateFormat(), $value)) { + return $dt->format("Y-m-d"); + } + + throw new TransformationFailedException(sprintf('Failed to transform "%s" using format "%s"', $value, $lang->getDateFormat())); + } + + /** + * Transforms a value from the transformed representation to its original + * representation. + * + * This method is called when {@link Form::bind()} is called to transform the requests tainted data + * into an acceptable format for your data processing/model layer. + * + * This method must be able to deal with empty values. Usually this will + * be an empty string, but depending on your implementation other empty + * values are possible as well (such as empty strings). The reasoning behind + * this is that value transformers must be chainable. If the + * reverseTransform() method of the first value transformer outputs an + * empty string, the second value transformer must be able to process that + * value. + * + * By convention, reverseTransform() should return NULL if an empty string + * is passed. + * + * @param mixed $value The value in the transformed representation + * + * @return mixed The value in the original representation + * + * @throws TransformationFailedException When the transformation fails. + */ + public function reverseTransform($value) + { + if (empty($value)) return ''; + + // Get the default language + $lang = LangQuery::create()->findOneByByDefault(1); + + if (false !== $dt = \DateTime::createFromFormat('Y-m-d', $value)) { + return $dt->format($lang->getDateFormat()); + } + + throw new TransformationFailedException(sprintf('Failed to reverse transform "%s" using format "%s"', $value, $lang->getDateFormat())); + } +} \ No newline at end of file From 3b7589ec84a7a7a4134fb13171acecff30182250 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 18:23:04 +0200 Subject: [PATCH 28/48] Removed useless transactions --- core/lib/Thelia/Model/Coupon.php | 426 +++++++++++++++---------------- 1 file changed, 203 insertions(+), 223 deletions(-) diff --git a/core/lib/Thelia/Model/Coupon.php b/core/lib/Thelia/Model/Coupon.php index b0d860ba4..cced6beb7 100644 --- a/core/lib/Thelia/Model/Coupon.php +++ b/core/lib/Thelia/Model/Coupon.php @@ -1,223 +1,203 @@ -. */ -/* */ -/**********************************************************************************/ - -namespace Thelia\Model; - -use Propel\Runtime\Propel; -use Thelia\Model\Base\Coupon as BaseCoupon; -use Thelia\Model\Exception\InvalidArgumentException; -use Thelia\Model\Map\CouponTableMap; - -/** - * 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 - * - */ -class Coupon extends BaseCoupon -{ - - use \Thelia\Model\Tools\ModelEventDispatcherTrait; - - /** - * Create or Update this Coupon - * - * @param string $code Coupon Code - * @param string $title Coupon title - * @param array $effects Ready to be serialized in JSON effect params - * @param string $type Coupon type - * @param bool $isRemovingPostage Is removing Postage - * @param string $shortDescription Coupon short description - * @param string $description Coupon description - * @param boolean $isEnabled Enable/Disable - * @param \DateTime $expirationDate Coupon expiration date - * @param boolean $isAvailableOnSpecialOffers Is available on special offers - * @param boolean $isCumulative Is cumulative - * @param int $maxUsage Coupon quantity - * @param string $defaultSerializedRule Serialized default rule added if none found - * @param string $locale Coupon Language code ISO (ex: fr_FR) - * - * @throws \Exception - */ - public function createOrUpdate($code, $title, array $effects, $type, $isRemovingPostage, $shortDescription, $description, $isEnabled, $expirationDate, $isAvailableOnSpecialOffers, $isCumulative, $maxUsage, $defaultSerializedRule, $locale = null) - { - $this->setCode($code) - ->setType($type) - ->setEffects($effects) - ->setIsRemovingPostage($isRemovingPostage) - ->setIsEnabled($isEnabled) - ->setExpirationDate($expirationDate) - ->setIsAvailableOnSpecialOffers($isAvailableOnSpecialOffers) - ->setIsCumulative($isCumulative) - ->setMaxUsage($maxUsage); - $this->setTitle($title) - ->setShortDescription($shortDescription) - ->setDescription($description); - - // If no rule given, set default rule - if (null === $this->getSerializedConditions()) { - $this->setSerializedConditions($defaultSerializedRule); - } - - // Set object language (i18n) - if (!is_null($locale)) { - $this->setLocale($locale); - } - - $con = Propel::getWriteConnection(CouponTableMap::DATABASE_NAME); - $con->beginTransaction(); - try { - $this->save($con); - $con->commit(); - - } catch (\Exception $e) { - $con->rollback(); - throw $e; - } - } - - /** - * Create or Update this coupon condition - * - * @param string $serializableConditions Serialized conditions ready to be saved - * @param string $locale Coupon Language code ISO (ex: fr_FR) - * - * @throws \Exception - */ - public function createOrUpdateConditions($serializableConditions, $locale) - { - $this->setSerializedConditions($serializableConditions); - - // Set object language (i18n) - if (!is_null($locale)) { - $this->setLocale($locale); - } - - $con = Propel::getWriteConnection(CouponTableMap::DATABASE_NAME); - $con->beginTransaction(); - try { - $this->save($con); - $con->commit(); - } catch (\Exception $e) { - $con->rollback(); - throw $e; - } - } - - /** - * Set Coupon amount - * - * @param float $amount Amount deduced from the Cart - * - * @return $this - */ - public function setAmount($amount) - { - $effects = $this->unserializeEffects($this->getSerializedEffects()); - $effects['amount'] = floatval($amount); - $this->setEffects($effects); - - return $this; - } - - /** - * Get the amount removed from the coupon to the cart - * - * @return float - */ - public function getAmount() - { - $amount = $this->getEffects()['amount']; - - return floatval($amount); - } - - /** - * Get the Coupon effects - * - * @return array - * @throws Exception\InvalidArgumentException - */ - public function getEffects() - { - $effects = $this->unserializeEffects($this->getSerializedEffects()); - - if (null === $effects['amount']) { - throw new InvalidArgumentException('Missing key \'amount\' in Coupon effect coming from database'); - } - - return $effects; - } - - /** - * Get the Coupon effects - * - * @param array $effects Effect ready to be serialized - * Needs at least the key 'amount' - * with the amount removed from the cart - * - * @throws Exception\InvalidArgumentException - * @return $this - */ - public function setEffects(array $effects) - { - if (null === $effects['amount']) { - throw new InvalidArgumentException('Missing key \'amount\' in Coupon effect ready to be serialized array'); - } - - $this->setSerializedEffects($this->serializeEffects($effects)); - - return $this; - } - - /** - * Return unserialized effects - * - * @param string $serializedEffects Serialized effect string to unserialize - * - * @return array - */ - public function unserializeEffects($serializedEffects) - { - $effects = json_decode($serializedEffects, true); - - return $effects; - } - - /** - * Return serialized effects - * - * @param array $unserializedEffects Unserialized array string to serialize - * - * @return string - */ - public function serializeEffects(array $unserializedEffects) - { - $effects = json_encode($unserializedEffects); - - return $effects; - } -} +. */ +/* */ +/**********************************************************************************/ + +namespace Thelia\Model; + +use Propel\Runtime\Propel; +use Thelia\Model\Base\Coupon as BaseCoupon; +use Thelia\Model\Exception\InvalidArgumentException; +use Thelia\Model\Map\CouponTableMap; + +/** + * 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 + * + */ +class Coupon extends BaseCoupon +{ + + use \Thelia\Model\Tools\ModelEventDispatcherTrait; + + /** + * Create or Update this Coupon + * + * @param string $code Coupon Code + * @param string $title Coupon title + * @param array $effects Ready to be serialized in JSON effect params + * @param string $type Coupon type + * @param bool $isRemovingPostage Is removing Postage + * @param string $shortDescription Coupon short description + * @param string $description Coupon description + * @param boolean $isEnabled Enable/Disable + * @param \DateTime $expirationDate Coupon expiration date + * @param boolean $isAvailableOnSpecialOffers Is available on special offers + * @param boolean $isCumulative Is cumulative + * @param int $maxUsage Coupon quantity + * @param string $defaultSerializedRule Serialized default rule added if none found + * @param string $locale Coupon Language code ISO (ex: fr_FR) + * + * @throws \Exception + */ + public function createOrUpdate($code, $title, array $effects, $type, $isRemovingPostage, $shortDescription, $description, $isEnabled, $expirationDate, $isAvailableOnSpecialOffers, $isCumulative, $maxUsage, $defaultSerializedRule, $locale = null) + { + $this + ->setCode($code) + ->setType($type) + ->setEffects($effects) + ->setIsRemovingPostage($isRemovingPostage) + ->setIsEnabled($isEnabled) + ->setExpirationDate($expirationDate) + ->setIsAvailableOnSpecialOffers($isAvailableOnSpecialOffers) + ->setIsCumulative($isCumulative) + ->setMaxUsage($maxUsage) + ->setLocale($locale) + ->setTitle($title) + ->setShortDescription($shortDescription) + ->setDescription($description); + + // If no rule given, set default rule + if (null === $this->getSerializedConditions()) { + $this->setSerializedConditions($defaultSerializedRule); + } + + $this->save(); + } + + /** + * Create or Update this coupon condition + * + * @param string $serializableConditions Serialized conditions ready to be saved + * @param string $locale Coupon Language code ISO (ex: fr_FR) + * + * @throws \Exception + */ + public function createOrUpdateConditions($serializableConditions, $locale) + { + $this->setSerializedConditions($serializableConditions); + + // Set object language (i18n) + if (!is_null($locale)) { + $this->setLocale($locale); + } + + $this->save(); + } + + /** + * Set Coupon amount + * + * @param float $amount Amount deduced from the Cart + * + * @return $this + */ + public function setAmount($amount) + { + $effects = $this->unserializeEffects($this->getSerializedEffects()); + $effects['amount'] = floatval($amount); + $this->setEffects($effects); + + return $this; + } + + /** + * Get the amount removed from the coupon to the cart + * + * @return float + */ + public function getAmount() + { + $amount = $this->getEffects()['amount']; + + return floatval($amount); + } + + /** + * Get the Coupon effects + * + * @return array + * @throws Exception\InvalidArgumentException + */ + public function getEffects() + { + $effects = $this->unserializeEffects($this->getSerializedEffects()); + + if (null === $effects['amount']) { + throw new InvalidArgumentException('Missing key \'amount\' in Coupon effect coming from database'); + } + + return $effects; + } + + /** + * Get the Coupon effects + * + * @param array $effects Effect ready to be serialized + * Needs at least the key 'amount' + * with the amount removed from the cart + * + * @throws Exception\InvalidArgumentException + * @return $this + */ + public function setEffects(array $effects) + { + if (null === $effects['amount']) { + throw new InvalidArgumentException('Missing key \'amount\' in Coupon effect ready to be serialized array'); + } + + $this->setSerializedEffects($this->serializeEffects($effects)); + + return $this; + } + + /** + * Return unserialized effects + * + * @param string $serializedEffects Serialized effect string to unserialize + * + * @return array + */ + public function unserializeEffects($serializedEffects) + { + $effects = json_decode($serializedEffects, true); + + return $effects; + } + + /** + * Return serialized effects + * + * @param array $unserializedEffects Unserialized array string to serialize + * + * @return string + */ + public function serializeEffects(array $unserializedEffects) + { + $effects = json_encode($unserializedEffects); + + return $effects; + } +} From 5e3585766d9290a94bc6d0f9c20e94f5c39fc6ee Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 18:23:36 +0200 Subject: [PATCH 29/48] Added a localized check to the expiration date --- core/lib/Thelia/Form/CouponCreationForm.php | 44 +++++++++++++++------ 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/core/lib/Thelia/Form/CouponCreationForm.php b/core/lib/Thelia/Form/CouponCreationForm.php index 05acf2c4e..0d5bf8835 100644 --- a/core/lib/Thelia/Form/CouponCreationForm.php +++ b/core/lib/Thelia/Form/CouponCreationForm.php @@ -12,11 +12,13 @@ namespace Thelia\Form; -use Symfony\Component\Validator\Constraints\Date; +use Symfony\Component\Validator\Constraints\Callback; use Symfony\Component\Validator\Constraints\GreaterThanOrEqual; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotEqualTo; -use Thelia\Coupon\ExpirationDateTransformer; +use Symfony\Component\Validator\ExecutionContextInterface; +use Thelia\Core\Translation\Translator; +use Thelia\Model\Base\LangQuery; /** * Allow to build a form Coupon @@ -91,16 +93,18 @@ class CouponCreationForm extends BaseForm array() ) ->add( - $this->formBuilder->create( - 'expirationDate', - 'text', - array( - 'constraints' => array( - new NotBlank(), - //new Date() - ) + 'expirationDate', + 'text', + array( + 'constraints' => array( + new NotBlank(), + new Callback(array( + "methods" => array( + array($this, "checkLocalizedDate"), + ), + )) ) - )->addViewTransformer(new ExpirationDateTransformer()) + ) ) ->add( 'isCumulative', @@ -142,6 +146,24 @@ class CouponCreationForm extends BaseForm ); } + /** + * Validate a date entered with the default Language date format. + * + * @param string $value + * @param ExecutionContextInterface $context + */ + public function checkLocalizedDate($value, ExecutionContextInterface $context) + { + $format = LangQuery::create()->findOneByByDefault(true)->getDateFormat(); + + if (false === \DateTime::createFromFormat($format, $value)) { + $context->addViolation(Translator::getInstance()->trans("Date '%date' is invalid, please enter a valid date using %fmt format", [ + '%fmt' => $format, + '%date' => $value + ])); + } + } + /** * Get form name * From 23a74999e80d2a306562d04286c2a9e29e91f55d Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 18:24:15 +0200 Subject: [PATCH 30/48] =?UTF-8?q?Fixed=20date=20manipulation=C2=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/lib/Thelia/Controller/Admin/CouponController.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/CouponController.php b/core/lib/Thelia/Controller/Admin/CouponController.php index e0564e0c2..fc4e3e887 100644 --- a/core/lib/Thelia/Controller/Admin/CouponController.php +++ b/core/lib/Thelia/Controller/Admin/CouponController.php @@ -172,7 +172,7 @@ class CouponController extends BaseAdminController 'shortDescription' => $coupon->getShortDescription(), 'description' => $coupon->getDescription(), 'isEnabled' => $coupon->getIsEnabled(), - 'expirationDate' => $coupon->getExpirationDate(), + 'expirationDate' => $coupon->getExpirationDate($this->getDefaultDateFormat()), 'isAvailableOnSpecialOffers' => $coupon->getIsAvailableOnSpecialOffers(), 'isCumulative' => $coupon->getIsCumulative(), 'isRemovingPostage' => $coupon->getIsRemovingPostage(), @@ -506,7 +506,8 @@ class CouponController extends BaseAdminController } catch (\Exception $e) { // Any other error - $message = 'Sorry, an error occurred:'; + $message = $this->getTranslator()->trans('Sorry, an error occurred: %err', ['%err' => $e->getMessage()]); + $this->logError($action, $message, $e); } @@ -717,7 +718,7 @@ class CouponController extends BaseAdminController $data['shortDescription'], $data['description'], $data['isEnabled'], - $data['expirationDate'], + \DateTime::createFromFormat($this->getDefaultDateFormat(), $data['expirationDate']), $data['isAvailableOnSpecialOffers'], $data['isCumulative'], $data['isRemovingPostage'], @@ -801,6 +802,7 @@ class CouponController extends BaseAdminController ) ); } + protected function getDefaultDateFormat() { return LangQuery::create()->findOneByByDefault(true)->getDateFormat(); From 207911492e5af5ba1ed2aa63ddc7cfdcdba89e43 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 18:25:03 +0200 Subject: [PATCH 31/48] Added flags for i18n fields --- templates/backOffice/default/coupon/form.html | 67 ++++++++++--------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/templates/backOffice/default/coupon/form.html b/templates/backOffice/default/coupon/form.html index e4bd0e22e..695dc1e01 100644 --- a/templates/backOffice/default/coupon/form.html +++ b/templates/backOffice/default/coupon/form.html @@ -48,8 +48,8 @@
    {form_field form=$form field='code'}
    - - + + {intl l='This is the code entered by your customers to use this coupon'} {if $error}{$message}{/if}
    @@ -97,13 +97,9 @@ {form_field form=$form field='expirationDate'}
    - - -
    - - {if $error}{$message}{/if} -
    - + + + {if $error}{$message}{/if}
    {/form_field} @@ -126,9 +122,9 @@
    {form_field form=$form field='type'}
    - - + {foreach from=$availableCoupons item=availableCoupon}
    From 8bf94517f256543d13e7ef9115521b9072668fed Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 18:25:31 +0200 Subject: [PATCH 32/48] No longer used --- .../Coupon/ExpirationDateTransformer.php | 105 ------------------ 1 file changed, 105 deletions(-) delete mode 100644 core/lib/Thelia/Coupon/ExpirationDateTransformer.php diff --git a/core/lib/Thelia/Coupon/ExpirationDateTransformer.php b/core/lib/Thelia/Coupon/ExpirationDateTransformer.php deleted file mode 100644 index f63d8ebdd..000000000 --- a/core/lib/Thelia/Coupon/ExpirationDateTransformer.php +++ /dev/null @@ -1,105 +0,0 @@ - - * - * Creation date: 02/05/14 15:20 - */ -class ExpirationDateTransformer implements DataTransformerInterface -{ - - /** - * Transforms a value from the original representation to a transformed representation. - * - * This method is called on two occasions inside a form field: - * - * 1. When the form field is initialized with the data attached from the datasource (object or array). - * 2. When data from a request is bound using {@link Form::bind()} to transform the new input data - * back into the renderable format. For example if you have a date field and bind '2009-10-10' onto - * it you might accept this value because its easily parsed, but the transformer still writes back - * "2009/10/10" onto the form field (for further displaying or other purposes). - * - * This method must be able to deal with empty values. Usually this will - * be NULL, but depending on your implementation other empty values are - * possible as well (such as empty strings). The reasoning behind this is - * that value transformers must be chainable. If the transform() method - * of the first value transformer outputs NULL, the second value transformer - * must be able to process that value. - * - * By convention, transform() should return an empty string if NULL is - * passed. - * - * @param mixed $value The value in the original representation - * - * @return mixed The value in the transformed representation - * - * @throws TransformationFailedException When the transformation fails. - */ - public function transform($value) - { - if (empty($value)) return ''; - - // Get the default language - $lang = LangQuery::create()->findOneByByDefault(1); - - if (false !== $dt = \DateTime::createFromFormat($lang->getDateFormat(), $value)) { - return $dt->format("Y-m-d"); - } - - throw new TransformationFailedException(sprintf('Failed to transform "%s" using format "%s"', $value, $lang->getDateFormat())); - } - - /** - * Transforms a value from the transformed representation to its original - * representation. - * - * This method is called when {@link Form::bind()} is called to transform the requests tainted data - * into an acceptable format for your data processing/model layer. - * - * This method must be able to deal with empty values. Usually this will - * be an empty string, but depending on your implementation other empty - * values are possible as well (such as empty strings). The reasoning behind - * this is that value transformers must be chainable. If the - * reverseTransform() method of the first value transformer outputs an - * empty string, the second value transformer must be able to process that - * value. - * - * By convention, reverseTransform() should return NULL if an empty string - * is passed. - * - * @param mixed $value The value in the transformed representation - * - * @return mixed The value in the original representation - * - * @throws TransformationFailedException When the transformation fails. - */ - public function reverseTransform($value) - { - if (empty($value)) return ''; - - // Get the default language - $lang = LangQuery::create()->findOneByByDefault(1); - - if (false !== $dt = \DateTime::createFromFormat('Y-m-d', $value)) { - return $dt->format($lang->getDateFormat()); - } - - throw new TransformationFailedException(sprintf('Failed to reverse transform "%s" using format "%s"', $value, $lang->getDateFormat())); - } -} \ No newline at end of file From e0027c7f6e181aca4a718207cd04652bf8131327 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 19:58:42 +0200 Subject: [PATCH 33/48] The stanck trace is displayed if an exception is thrown --- setup/faker.php | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/faker.php b/setup/faker.php index 3cc54b741..4ae74a0e5 100644 --- a/setup/faker.php +++ b/setup/faker.php @@ -502,6 +502,7 @@ try { } catch (Exception $e) { echo "error : ".$e->getMessage()."\n"; + echo $e->getTraceAsString(); $con->rollBack(); } From 98f4395a079edafae727b7feb893703f236b638f Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 19:59:33 +0200 Subject: [PATCH 34/48] Removed unused parser reference in contructor --- core/lib/Thelia/Condition/Implementation/ConditionAbstract.php | 1 - 1 file changed, 1 deletion(-) diff --git a/core/lib/Thelia/Condition/Implementation/ConditionAbstract.php b/core/lib/Thelia/Condition/Implementation/ConditionAbstract.php index 5ddf4f6e4..bae7fcf31 100644 --- a/core/lib/Thelia/Condition/Implementation/ConditionAbstract.php +++ b/core/lib/Thelia/Condition/Implementation/ConditionAbstract.php @@ -65,7 +65,6 @@ abstract class ConditionAbstract implements ConditionInterface { $this->facade = $facade; $this->translator = $facade->getTranslator(); - $this->parser = $facade->getParser(); $this->conditionValidator = $facade->getConditionEvaluator(); } From 7781fe5f59e3605475a8e50bba86d576ac412295 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 20:00:19 +0200 Subject: [PATCH 35/48] Minor syntax change. --- core/lib/Thelia/Form/CouponCreationForm.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/core/lib/Thelia/Form/CouponCreationForm.php b/core/lib/Thelia/Form/CouponCreationForm.php index 0d5bf8835..a42ad85da 100644 --- a/core/lib/Thelia/Form/CouponCreationForm.php +++ b/core/lib/Thelia/Form/CouponCreationForm.php @@ -127,11 +127,7 @@ class CouponCreationForm extends BaseForm array( 'constraints' => array( new NotBlank(), - new GreaterThanOrEqual( - array( - 'value' => -1 - ) - ) + new GreaterThanOrEqual(['value' => -1]) ) ) ) From 4bab22342118ebd7c865e78774ceb053be9267d0 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 20:01:18 +0200 Subject: [PATCH 36/48] Fixed usage count display --- templates/backOffice/default/coupon/form.html | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/templates/backOffice/default/coupon/form.html b/templates/backOffice/default/coupon/form.html index 695dc1e01..216ee8685 100644 --- a/templates/backOffice/default/coupon/form.html +++ b/templates/backOffice/default/coupon/form.html @@ -107,11 +107,12 @@
    + - + {if $error}{$message}{/if}
    {/form_field} From 621c17c97d8faf065c7b8e473c65944776aa8aaf Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 20:08:38 +0200 Subject: [PATCH 37/48] Fixed form error management --- .../Controller/Admin/CouponController.php | 54 +++++++++---------- .../backOffice/default/assets/js/coupon.js | 36 +++++++------ 2 files changed, 44 insertions(+), 46 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/CouponController.php b/core/lib/Thelia/Controller/Admin/CouponController.php index fc4e3e887..16771b78b 100644 --- a/core/lib/Thelia/Controller/Admin/CouponController.php +++ b/core/lib/Thelia/Controller/Admin/CouponController.php @@ -77,15 +77,10 @@ class CouponController extends BaseAdminController // Parameters given to the template $args = []; - $i18n = new I18n(); - /** @var Lang $lang */ - $lang = $this->getSession()->getLang(); $eventToDispatch = TheliaEvents::COUPON_CREATE; if ($this->getRequest()->isMethod('POST')) { $this->validateCreateOrUpdateForm( - $i18n, - $lang, $eventToDispatch, 'created', 'creation' @@ -140,16 +135,11 @@ class CouponController extends BaseAdminController // Parameters given to the template $args = []; - $i18n = new I18n(); - /** @var Lang $lang */ - $lang = $this->getSession()->getLang(); $eventToDispatch = TheliaEvents::COUPON_UPDATE; // Update if ($this->getRequest()->isMethod('POST')) { $this->validateCreateOrUpdateForm( - $i18n, - $lang, $eventToDispatch, 'updated', 'update', @@ -189,6 +179,7 @@ class CouponController extends BaseAdminController // Pass it to the parser $this->getParserContext()->addForm($changeForm); } + $args['couponCode'] = $coupon->getCode(); $args['availableCoupons'] = $this->getAvailableCoupons(); $args['couponInputsHtml'] = $couponManager->drawBackOfficeInputs(); @@ -456,8 +447,6 @@ class CouponController extends BaseAdminController /** * Validate the CreateOrUpdate form * - * @param I18n $i18n Local code (fr_FR) - * @param Lang $lang Local variables container * @param string $eventToDispatch Event which will activate actions * @param string $log created|edited * @param string $action creation|edition @@ -465,15 +454,15 @@ class CouponController extends BaseAdminController * * @return $this */ - protected function validateCreateOrUpdateForm(I18n $i18n, Lang $lang, $eventToDispatch, $log, $action, Coupon $model = null) + protected function validateCreateOrUpdateForm($eventToDispatch, $log, $action, Coupon $model = null) { // Create the form from the request - $creationForm = new CouponCreationForm($this->getRequest()); + $couponForm = new CouponCreationForm($this->getRequest()); $message = false; try { // Check the form against conditions violations - $form = $this->validateForm($creationForm, 'POST'); + $form = $this->validateForm($couponForm, 'POST'); $couponEvent = $this->feedCouponCreateOrUpdateEvent($form, $model); @@ -492,32 +481,39 @@ class CouponController extends BaseAdminController ) ); - $this->redirect( - str_replace( - '{id}', - $couponEvent->getCouponModel()->getId(), - $creationForm->getSuccessUrl() - ) - ); + if ($this->getRequest()->get('save_mode') == 'stay') { + $this->redirect( + str_replace( + '{id}', + $couponEvent->getCouponModel()->getId(), + $couponForm->getSuccessUrl() + ) + ); - } catch (FormValidationException $e) { + exit(); + } + + // Redirect to the success URL + $this->redirectToRoute('admin.coupon.list'); + + } catch (FormValidationException $ex) { // Invalid data entered - $message = 'Please check your input:'; + $message = $this->createStandardFormValidationErrorMessage($ex); - } catch (\Exception $e) { + } catch (\Exception $ex) { // Any other error - $message = $this->getTranslator()->trans('Sorry, an error occurred: %err', ['%err' => $e->getMessage()]); + $message = $this->getTranslator()->trans('Sorry, an error occurred: %err', ['%err' => $ex->getMessage()]); - $this->logError($action, $message, $e); + $this->logError($action, $message, $ex); } if ($message !== false) { // Mark the form as with error - $creationForm->setErrorMessage($message); + $couponForm->setErrorMessage($message); // Send the form and the error to the parser $this->getParserContext() - ->addForm($creationForm) + ->addForm($couponForm) ->setGeneralError($message); } diff --git a/templates/backOffice/default/assets/js/coupon.js b/templates/backOffice/default/assets/js/coupon.js index de83da5be..7e7780f30 100644 --- a/templates/backOffice/default/assets/js/coupon.js +++ b/templates/backOffice/default/assets/js/coupon.js @@ -56,7 +56,7 @@ $(function($){ $('#condition-list').html($.couponManager.intlPleaseSelectAnotherCondition); } } - }).done(function(data) { + }).done(function() { // Reload condition summaries ajax $.couponManager.displayConditionsSummary(); }); @@ -207,24 +207,9 @@ $(function($){ }; - - // *********************************************** // *************** Manager Coupon **************** // *********************************************** - // Reload effect inputs when changing effect - $.couponManager.onEffectChange = function() { - var mainDiv = $('#coupon-type'); - var optionSelected = mainDiv.find('#type option:selected'); - mainDiv.find('.typeToolTip').html(optionSelected.data('description')); - - mainDiv.find('#type').on('change', function () { - var optionSelected = $('option:selected', this); - $.couponManager.displayEfffect(optionSelected); - - }); - }; - $.couponManager.onEffectChange(); $.couponManager.displayEfffect = function(optionSelected) { var mainDiv = $('#coupon-type'); @@ -251,6 +236,20 @@ $(function($){ }); }; + // Reload effect inputs when changing effect + $.couponManager.onEffectChange = function() { + var mainDiv = $('#coupon-type'); + var optionSelected = mainDiv.find('#type option:selected'); + mainDiv.find('.typeToolTip').html(optionSelected.data('description')); + + mainDiv.find('#type').on('change', function () { + var optionSelected = $('option:selected', this); + $.couponManager.displayEfffect(optionSelected); + + }); + }; + $.couponManager.onEffectChange(); + $.couponManager.displayConditionsSummary = function() { var mainDiv = $('#condition-list'); mainDiv.html('
    '); @@ -277,7 +276,9 @@ $(function($){ // Set max usage to unlimited or not $.couponManager.onUsageUnlimitedChange = function() { var $isUnlimited = $('#is-unlimited'); - $maxUsage = $('#max-usage'); + + var $maxUsage = $('#max-usage'); + if ($maxUsage.val() == -1) { $isUnlimited.prop('checked', true); $maxUsage.hide(); @@ -299,5 +300,6 @@ $(function($){ } }); }; + $.couponManager.onUsageUnlimitedChange(); }); \ No newline at end of file From 617f2900e0da2d2c09968a5ab88f5ab1e408f891 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 20:21:33 +0200 Subject: [PATCH 38/48] Fixed test --- .../lib/Thelia/Tests/Condition/OperatorsTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/lib/Thelia/Tests/Condition/OperatorsTest.php b/core/lib/Thelia/Tests/Condition/OperatorsTest.php index a71f8e666..c410fd975 100644 --- a/core/lib/Thelia/Tests/Condition/OperatorsTest.php +++ b/core/lib/Thelia/Tests/Condition/OperatorsTest.php @@ -44,35 +44,35 @@ class OperatorsTest extends \PHPUnit_Framework_TestCase ->will($this->returnCallback((array($this, 'callbackI18n')))); $actual = Operators::getI18n($stubTranslator, Operators::INFERIOR); - $expected = 'inferior to'; + $expected = 'Less than'; $this->assertEquals($expected, $actual); $actual = Operators::getI18n($stubTranslator, Operators::INFERIOR_OR_EQUAL); - $expected = 'inferior or equal to'; + $expected = 'Less than or equals'; $this->assertEquals($expected, $actual); $actual = Operators::getI18n($stubTranslator, Operators::EQUAL); - $expected = 'equal to'; + $expected = 'Equals'; $this->assertEquals($expected, $actual); $actual = Operators::getI18n($stubTranslator, Operators::SUPERIOR_OR_EQUAL); - $expected = 'superior or equal to'; + $expected = 'Greater than or equals'; $this->assertEquals($expected, $actual); $actual = Operators::getI18n($stubTranslator, Operators::SUPERIOR); - $expected = 'superior to'; + $expected = 'Greater than'; $this->assertEquals($expected, $actual); $actual = Operators::getI18n($stubTranslator, Operators::DIFFERENT); - $expected = 'different from'; + $expected = 'Not equals'; $this->assertEquals($expected, $actual); $actual = Operators::getI18n($stubTranslator, Operators::IN); - $expected = 'in'; + $expected = 'In'; $this->assertEquals($expected, $actual); $actual = Operators::getI18n($stubTranslator, Operators::OUT); - $expected = 'not in'; + $expected = 'Not in'; $this->assertEquals($expected, $actual); $actual = Operators::getI18n($stubTranslator, 'unexpected operator'); From fe93bfacecc34ed84e1fa22a0cd3ea3c8f11994b Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 20:22:10 +0200 Subject: [PATCH 39/48] Typo --- core/lib/Thelia/Condition/Operators.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/Thelia/Condition/Operators.php b/core/lib/Thelia/Condition/Operators.php index 7d2ae1485..0d0600967 100644 --- a/core/lib/Thelia/Condition/Operators.php +++ b/core/lib/Thelia/Condition/Operators.php @@ -68,7 +68,7 @@ abstract class Operators break; case self::EQUAL: $ret = $translator->trans( - 'Equals to', + 'Equals', [], 'condition' ); From 500a945f98532dd062b0443bbe35aa5f8ced4ae6 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 20:52:59 +0200 Subject: [PATCH 40/48] HTML fragments in templates instead of hardcoded --- core/lib/Thelia/Coupon/Type/RemoveXAmount.php | 9 +++++++++ .../lib/Thelia/Coupon/Type/RemoveXPercent.php | 19 +++++++------------ .../type-fragments/remove-x-amount.html | 9 +++++++++ .../type-fragments/remove-x-percent.html | 8 ++++++++ 4 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 templates/backOffice/default/coupon/type-fragments/remove-x-amount.html create mode 100644 templates/backOffice/default/coupon/type-fragments/remove-x-percent.html diff --git a/core/lib/Thelia/Coupon/Type/RemoveXAmount.php b/core/lib/Thelia/Coupon/Type/RemoveXAmount.php index 5ee212b27..c644706a2 100644 --- a/core/lib/Thelia/Coupon/Type/RemoveXAmount.php +++ b/core/lib/Thelia/Coupon/Type/RemoveXAmount.php @@ -65,4 +65,13 @@ class RemoveXAmount extends CouponAbstract return $toolTip; } + + public function drawBackOfficeInputs() + { + return $this->facade->getParser()->render('coupon/type-fragments/remove-x-amount.html', [ + 'label' => $this->getInputName(), + 'fieldName' => self::INPUT_AMOUNT_NAME, + 'value' => $this->amount + ]); + } } diff --git a/core/lib/Thelia/Coupon/Type/RemoveXPercent.php b/core/lib/Thelia/Coupon/Type/RemoveXPercent.php index db0a011ea..83c625d9c 100644 --- a/core/lib/Thelia/Coupon/Type/RemoveXPercent.php +++ b/core/lib/Thelia/Coupon/Type/RemoveXPercent.php @@ -145,17 +145,12 @@ class RemoveXPercent extends CouponAbstract */ public function drawBackOfficeInputs() { - $labelPercentage = $this->getInputName(); - - $html = ' - -
    - - -
    - '; - - return $html; + return $this->facade->getParser()->render('coupon/type-fragments/remove-x-percent.html', [ + 'label' => $this->getInputName(), + 'typeKey' => self::INPUT_AMOUNT_NAME, + 'fieldId' => self::INPUT_PERCENTAGE_NAME, + 'fieldName' => self::INPUT_EXTENDED__NAME, + 'value' => $this->percentage + ]); } - } diff --git a/templates/backOffice/default/coupon/type-fragments/remove-x-amount.html b/templates/backOffice/default/coupon/type-fragments/remove-x-amount.html new file mode 100644 index 000000000..6159af73f --- /dev/null +++ b/templates/backOffice/default/coupon/type-fragments/remove-x-amount.html @@ -0,0 +1,9 @@ +
    + +
    + + {loop type="currency" name="get-symbol" default_only="true"} +
    {$SYMBOL}
    + {/loop} +
    +
    diff --git a/templates/backOffice/default/coupon/type-fragments/remove-x-percent.html b/templates/backOffice/default/coupon/type-fragments/remove-x-percent.html new file mode 100644 index 000000000..7cd461a48 --- /dev/null +++ b/templates/backOffice/default/coupon/type-fragments/remove-x-percent.html @@ -0,0 +1,8 @@ + +
    + +
    + +
    %
    +
    +
    From 771f59ee473479741422e6a3cb2f223587bae102 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 20:54:17 +0200 Subject: [PATCH 41/48] Fixed condition category tolltip reset --- templates/backOffice/default/assets/js/coupon.js | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/backOffice/default/assets/js/coupon.js b/templates/backOffice/default/assets/js/coupon.js index 7e7780f30..74b511c82 100644 --- a/templates/backOffice/default/assets/js/coupon.js +++ b/templates/backOffice/default/assets/js/coupon.js @@ -95,6 +95,7 @@ $(function($){ ).done(function() { $.couponManager.displayConditionsSummary(); $('#condition-add-operators-values').html(''); + $('#condition-add-type').find('.typeToolTip').html(''); // Set the condition selector to default $("#category-condition option").filter(function() { return $(this).val() == ''; From 8c044303f2b578564315e826ee82f70f6cb9b1b4 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 20:54:53 +0200 Subject: [PATCH 42/48] drawBackOfficeInputs() is now abstract --- core/lib/Thelia/Coupon/Type/CouponAbstract.php | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/core/lib/Thelia/Coupon/Type/CouponAbstract.php b/core/lib/Thelia/Coupon/Type/CouponAbstract.php index 985960cfa..0653fbee2 100644 --- a/core/lib/Thelia/Coupon/Type/CouponAbstract.php +++ b/core/lib/Thelia/Coupon/Type/CouponAbstract.php @@ -353,20 +353,7 @@ abstract class CouponAbstract implements CouponInterface * * @return string HTML string */ - public function drawBackOfficeInputs() - { - $label = $this->getInputName(); - $value = $this->amount; - - $html = ' -
    - - -
    - '; - - return $html; - } + public abstract function drawBackOfficeInputs(); /** * Get all extended inputs name to manage From b3a89f35e32ddb77d5a0c5920c2457697b97e170 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 2 May 2014 20:55:27 +0200 Subject: [PATCH 43/48] Changed condition section title --- templates/backOffice/default/coupon/form.html | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/templates/backOffice/default/coupon/form.html b/templates/backOffice/default/coupon/form.html index 216ee8685..ed6fa4d2e 100644 --- a/templates/backOffice/default/coupon/form.html +++ b/templates/backOffice/default/coupon/form.html @@ -119,7 +119,6 @@
    -
    {form_field form=$form field='type'}
    @@ -180,21 +179,17 @@
    - -
    -
    - {intl l='Coupon conditions'} -
    -
    - -
    +
    {if $noConditions}
    +

    {intl l="Coupon conditions"}


    {include file='includes/notifications.html' type='info' dismissable=false message={intl l='Please save this coupon first to define coupon conditions'}}
    {else}
    +

    {intl l="Coupon conditions"}

    +
    @@ -211,10 +206,13 @@
    + +

    {intl l="Add a condition"}

    +
    - + +
    From 4673a14b768c4f6b1b569bb4cced8e92221841d1 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Mon, 5 May 2014 10:04:38 +0200 Subject: [PATCH 48/48] Typo --- core/lib/Thelia/Coupon/Type/CouponAbstract.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/Thelia/Coupon/Type/CouponAbstract.php b/core/lib/Thelia/Coupon/Type/CouponAbstract.php index c40bc9f88..5a2c5f03a 100644 --- a/core/lib/Thelia/Coupon/Type/CouponAbstract.php +++ b/core/lib/Thelia/Coupon/Type/CouponAbstract.php @@ -93,7 +93,7 @@ abstract class CouponAbstract implements CouponInterface * * @param FacadeInterface $facade Service facade */ - protected function __construct(FacadeInterface $facade) + public function __construct(FacadeInterface $facade) { $this->facade = $facade; $this->translator = $facade->getTranslator();