Add new payment and shipping parsers for various integrations

- Implemented Google Pay parser in bongooglepay.js
- Added Buckaroo 3 payment parser in buckaroo3.js
- Introduced DataTrans CW Mastercard parser in datatranscw.js
- Created DataTrans CW Credit Card parser in datatranscw_creditcard.js
- Developed DHL Assistant shipping parser in dhlassistant.js
- Added Estimated Delivery parser in estimateddelivery.js
- Implemented Floapay payment parser in floapay.js
- Created FS Pickup at Store shipping parser in fspickupatstore.js
- Developed Generic Iframe parser in generic_iframe_parser.js
- Added Geodis Officiel shipping parser in geodisofficiel.js
- Implemented Glob Kurier module shipping parser in globkuriermodule.js
- Created Latvija Post Express Pickup Terminal parser in latvijaspastsexpresspastspostterminalslv.js
- Developed LP Shipping parser in lpshipping.js
- Added Mijora Venipak parser in mijoravenipak.js
- Implemented Apple Pay parser in pm_applepay.js
- Created Przelewy24 payment parser in przelewy24.js
- Developed Pshugls shipping parser in pshugls.js
- Added Redsys Insite payment parser in redsysinsite.js
- Implemented Tpay payment parser in tpay.js
- Updated third-party integration documentation for FedEx DotCom
This commit is contained in:
2025-08-04 23:10:27 +02:00
parent 037a6c5551
commit d39433f0d4
125 changed files with 4986 additions and 1772 deletions

View File

@@ -32,7 +32,7 @@
{if $product.cover}
<img src="{$product.cover.bySize.cart_default.url}" alt="{$product.name|escape:'quotes'}">
{else}
<img src="{$urls.no_picture_image.bySize.cart_default.url}" />
<img src="{$urls.no_picture_image.bySize.cart_default.url|escape:'javascript':'UTF-8'}" />
{/if}
{/if}
</span>
@@ -42,95 +42,115 @@
<div class="product-line-body">
<div class="product-line-desc">
<div class="product-line-info product-title">
<a class="label" href="{$product.url}" data-id_customization="{$product.id_customization|intval}">{$product.name}</a>
<a class="label" href="{$product.url|escape:'javascript':'UTF-8'}"
data-id_customization="{$product.id_customization|intval}">{$product.name|escape:'javascript':'UTF-8'}</a>
</div>
<div class="product-line-info product-price h5 {if $product.has_discount}has-discount{/if} 11">
{if $product.has_discount}
<div class="product-line-info product-price h5 {if $product.has_discount}has-discount{/if}">
{if $product.has_discount|escape:'javascript':'UTF-8'}
<div class="product-discount">
<span class="regular-price">{$product.regular_price}</span>
<span class="regular-price">{$product.regular_price|escape:'javascript':'UTF-8'}</span>
{if $product.discount_type === 'percentage'}
<span class="discount discount-percentage">
-{$product.discount_percentage_absolute}
-{$product.discount_percentage_absolute|escape:'javascript':'UTF-8'}
</span>
{else}
<span class="discount discount-amount">
-{$product.discount_to_display}
-{$product.discount_to_display|escape:'javascript':'UTF-8'}
</span>
{/if}
</div>
{/if}
<div class="current-price">
<span class="price">{$product.price}</span>
<span class="price">{$product.price|escape:'javascript':'UTF-8'}</span>
{if $product.unit_price_full}
<div class="unit-price-cart">{$product.unit_price_full}</div>
<div class="unit-price-cart">{$product.unit_price_full|escape:'javascript':'UTF-8'}</div>
{/if}
</div>
</div>
<br />
<br/>
{foreach from=$product.attributes key="attribute" item="value"}
<div class="product-line-info product-attribute">
<span class="label">{$attribute}:</span>
<span class="value">{$value}</span>
<span class="label">{$attribute|escape:'htmlall':'UTF-8'}:</span>
<span class="value">{$value|escape:'htmlall':'UTF-8'}</span>
</div>
{/foreach}
{if $tc_config->show_product_stock_info} {*tc module config*}
<div class="product-line-info quantity-info">
<span class="{if $product.quantity_available <= 0 && !$product.allow_oosp}qty-label label-warning{else}qty-label label-success{/if}
{if $z_tc_config->show_product_stock_info} {*tc module config*}
<div class="product-line-info quantity-info">
<span class="{if $product.quantity_available <= 0 && !$product.allow_oosp}qty-label label-warning{else}qty-label label-success{/if}
{if $product.quantity_available <= 0} label-later{/if}">
{if $product.quantity_available <= 0}
{if $product.allow_oosp}
{if isset($product.available_later) && $product.available_later}
{$product.available_later}
{if $product.quantity_available <= 0}
{if $product.allow_oosp}
{if isset($product.available_later) && $product.available_later}
{$product.available_later|escape:'htmlall':'UTF-8'}
{else}
{*{$product.availability_message}*}
{l s='In supplier stock' mod='thecheckout'}
{/if}
{else}
{l s='Out of stock' mod='thecheckout'}
{/if}
{else}
{*{$product.availability_message}*}
{l s='In supplier stock' mod='thecheckout'}
{if isset($product.available_now) && $product.available_now}
{$product.available_now|escape:'htmlall':'UTF-8'}
{else}
{l s='In stock' d='Shop.Theme.Catalog'}
{/if}
{/if}
{else}
{l s='Out of stock' mod='thecheckout'}
{/if}
{else}
{if isset($product.available_now) && $product.available_now}
{$product.available_now}
{else}
{l s='In stock' d='Shop.Theme.Catalog'}
{/if}
{/if}
</span>
<div class='qty-insufficient-stock{if $product.quantity_available>=$product.quantity || $product.quantity_available<=0} hidden{/if}'>
<span class='qty-in-stock-only'>{l s='In stock only' mod='thecheckout'} {$product.quantity_available} {l s='pcs.' mod='thecheckout'}</span>
{if $product.allow_oosp}
<span class='qty-remaining-on'>{l s='Remaining pcs. in' mod='thecheckout'} {$product.available_later}</span>
{else}
<span class='qty-remaining-on no-longer-available'>{l s='Please adjust quantity' mod='thecheckout'}</span>
{/if}
</div>{*hook h="displayProductDeliveryTime" product=$product*}
</div>
{/if}
</span>
<div class='qty-insufficient-stock{if $product.quantity_available>=$product.quantity || $product.quantity_available<=0} hidden{/if}'>
<span class='qty-in-stock-only'>{l s='In stock only' mod='thecheckout'} {$product.quantity_available|escape:'htmlall':'UTF-8'} {l s='pcs.' mod='thecheckout'}</span>
{if $product.allow_oosp}
<span class='qty-remaining-on'>{l s='Remaining pcs. in' mod='thecheckout'} {$product.available_later|escape:'htmlall':'UTF-8'}</span>
{else}
<span class='qty-remaining-on no-longer-available'>{l s='Please adjust quantity' mod='thecheckout'}</span>
{/if}
</div>{*hook h="displayProductDeliveryTime" product=$product*}</div>
{/if}
{if $product.customizations|count}
<br>
{block name='cart_detailed_product_line_customization'}
{foreach from=$product.customizations item="customization"}
{foreach from=$customization.fields item="field"}
<div class="product-customization-line row">
<div class="col-12">
{$field.label}:
{if $field.type == 'text'}
{if (int)$field.id_module}
{$field.text nofilter}
{else}
{$field.text}
{/if}
{elseif $field.type == 'image'}
<img src="{$field.image.small.url}">
{/if}
<a href="#" data-toggle="modal"
data-target="#product-customizations-modal-{$customization.id_customization|escape:'javascript':'UTF-8'}">{l s='Product customization' d='Shop.Theme.Catalog'}</a>
<div class="modal fade customization-modal"
id="product-customizations-modal-{$customization.id_customization|escape:'javascript':'UTF-8'}" tabindex="-1" role="dialog"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">{l s='Product customization' d='Shop.Theme.Catalog'}</h4>
</div>
<div class="modal-body">
{foreach from=$customization.fields item="field"}
<div class="product-customization-line row">
<div class="col-sm-3 col-xs-4 label">
{$field.label|escape:'htmlall':'UTF-8'}
</div>
<div class="col-sm-9 col-xs-8 value">
{if $field.type == 'text'}
{if (int)$field.id_module}
{$field.text nofilter}
{else}
{$field.text|escape:'htmlall':'UTF-8'}
{/if}
{elseif $field.type == 'image'}
<img src="{$field.image.small.url|escape:'javascript':'UTF-8'}">
{/if}
</div>
</div>
{/foreach}
</div>
</div>
</div>
{/foreach}
</div>
{/foreach}
{/block}
{/if}
@@ -139,32 +159,59 @@
<!-- product left body: description -->
<div class="product-line-actions">
<div class="product-line-qty" data-qty-control="{$product.id_product|escape:'javascript':'UTF-8'}-{$product.id_product_attribute|escape:'javascript':'UTF-8'}-{$product.id_customization|escape:'javascript':'UTF-8'}">
<div class="product-line-qty"
data-qty-control="{$product.id_product|escape:'javascript':'UTF-8'}-{$product.id_product_attribute|escape:'javascript':'UTF-8'}-{$product.id_customization|escape:'javascript':'UTF-8'}">
<div class="qty-container">
<div class="qty-box">
{if isset($product.is_gift) && $product.is_gift}
<span class="gift-quantity">{$product.quantity}</span>
{else}
<input class="cart-line-product-quantity" data-link-action="x-update-cart-quantity" data-update-url="{$product.update_quantity_url}" data-id-product="{$product.id_product|escape:'javascript':'UTF-8'}" data-id-product-attribute="{$product.id_product_attribute|escape:'javascript':'UTF-8'}" data-id-customization="{$product.id_customization|escape:'javascript':'UTF-8'}" data-qty-orig="{$product.quantity|escape:'javascript':'UTF-8'}" type="text" value="{$product.quantity}" name="product-quantity-spin" min="{$product.minimal_quantity}" />
<a class="cart-line-product-quantity-up" href="{$product.up_quantity_url}" data-link-action="x-update-cart-quantity-up">{*Up*}</a>
<a class="cart-line-product-quantity-down" href="{$product.down_quantity_url}" data-link-action="x-update-cart-quantity-down">{*Down*}</a>
<input
class="cart-line-product-quantity"
data-link-action="x-update-cart-quantity"
data-update-url="{$product.update_quantity_url}"
data-id-product="{$product.id_product|escape:'javascript':'UTF-8'}"
data-id-product-attribute="{$product.id_product_attribute|escape:'javascript':'UTF-8'}"
data-id-customization="{$product.id_customization|escape:'javascript':'UTF-8'}"
data-qty-orig="{$product.quantity|escape:'javascript':'UTF-8'}"
{* data-step="{$product.minimal_quantity|escape:'javascript':'UTF-8'}"*}
type="text"
value="{$product.quantity}"
name="product-quantity-spin"
min="{$product.minimal_quantity}"
/>
<a class="cart-line-product-quantity-up"
href="{$product.up_quantity_url}"
data-link-action="x-update-cart-quantity-up">{*Up*}</a>
<a class="cart-line-product-quantity-down"
href="{$product.down_quantity_url}"
data-link-action="x-update-cart-quantity-down">{*Down*}</a>
{/if}
</div>
</div>
</div>
<div class="product-line-price">
<span class="product-price">
<strong>
{if isset($product.is_gift) && $product.is_gift}
<span class="gift">{l s='Gift' d='Shop.Theme.Checkout'}</span>
{else}
{$product.total}
{/if}
</strong>
</span>
<span class="product-price">
<strong>
{if isset($product.is_gift) && $product.is_gift}
<span class="gift">{l s='Gift' d='Shop.Theme.Checkout'}</span>
{else}
{$product.total}
{/if}
</strong>
</span>
</div>
<div class="product-line-delete">
<a class="remove-from-cart" rel="nofollow" href="{$product.remove_from_cart_url}" data-link-action="x-delete-from-cart" data-id-product="{$product.id_product|escape:'javascript':'UTF-8'}" data-id-product-attribute="{$product.id_product_attribute|escape:'javascript':'UTF-8'}" data-id-customization="{$product.id_customization|escape:'javascript':'UTF-8'}" title="{l s='Delete' d='Shop.Theme.Actions'}">
<a
class="remove-from-cart"
rel="nofollow"
href="{$product.remove_from_cart_url}"
data-link-action="x-delete-from-cart"
data-id-product="{$product.id_product|escape:'javascript':'UTF-8'}"
data-id-product-attribute="{$product.id_product_attribute|escape:'javascript':'UTF-8'}"
data-id-customization="{$product.id_customization|escape:'javascript':'UTF-8'}"
title="{l s='Delete' d='Shop.Theme.Actions'}"
>
{if !isset($product.is_gift) || !$product.is_gift}
<i class="material-icons delete-from-cart float-xs-left">delete</i>
<span class="non-material-icon delete-from-cart"></span>
@@ -178,4 +225,4 @@
{/block}
</div>
</div>
</div>

View File

@@ -31,15 +31,15 @@
<div class="card-block">
{foreach from=$cart.subtotals item="subtotal"}
{if isset($subtotal.value) && $subtotal.value && $subtotal.type !== 'tax'}
<div class="cart-summary-line{if $waitForShippingCls && 'products' != $subtotal.type}{$waitForShippingCls}{/if}{if !$subtotal.amount} free{/if}" id="cart-subtotal-{$subtotal.type}">
<div class="cart-summary-line{if $waitForShippingCls && 'products' != $subtotal.type}{$waitForShippingCls|escape:'javascript':'UTF-8'}{/if}{if !$subtotal.amount} free{/if}" id="cart-subtotal-{$subtotal.type|escape:'javascript':'UTF-8'}">
<span class="label{if 'products' === $subtotal.type} js-subtotal{/if}">
{if 'products' == $subtotal.type}
{$cart.summary_string}
{$cart.summary_string|escape:'htmlall':'UTF-8'}
{else}
{$subtotal.label}
{$subtotal.label|escape:'htmlall':'UTF-8'}
{/if}
</span>
<span class="value">{$subtotal.value}</span>
<span class="value">{$subtotal.value|escape:'htmlall':'UTF-8'}</span>
{if $subtotal.type === 'shipping'}
<div>
<small class="value">{hook h='displayCheckoutSubtotalDetails' subtotal=$subtotal}</small>
@@ -48,6 +48,7 @@
</div>
{/if}
{/foreach}
{hook h="displayPaymentRuleCartSummary"}
</div>
{block name='cart_voucher'}
@@ -59,34 +60,53 @@
<div class="card-block">
{if (isset($cart.subtotals.tax) && $cart.subtotals.tax.amount > 0) || (!$configuration.display_prices_tax_incl && $configuration.taxes_enabled) }
{* tax displayed in cart summary, we show Total (tax excl.), Tax and Total (tax incl.) *}
<div class="cart-summary-line cart-total-tax-excluded{$waitForShippingCls}">
<span class="label">{$cart.totals.total_excluding_tax.label}</span>
<span class="value">{$cart.totals.total_excluding_tax.value}</span>
<div class="cart-summary-line cart-total-tax-excluded{$waitForShippingCls|escape:'javascript':'UTF-8'}">
<span class="label">{$cart.totals.total_excluding_tax.label|escape:'htmlall':'UTF-8'}</span>
<span class="value">{$cart.totals.total_excluding_tax.value|escape:'htmlall':'UTF-8'}</span>
</div>
{if isset($cart.subtotals.tax)}
<div class="cart-summary-line cart-total-tax{$waitForShippingCls}">
<span class="label">{$cart.subtotals.tax.label}</span>
<span class="value">{$cart.subtotals.tax.value}</span>
<div class="cart-summary-line cart-total-tax{$waitForShippingCls|escape:'javascript':'UTF-8'}">
<div class="label" style="display: inline">{$cart.subtotals.tax.label|escape:'javascript':'UTF-8'}
{if $cart.totals.total_excluding_tax.amount > 0}
{math equation='(a/b)*100' a=$cart.subtotals.tax.amount b=$cart.totals.total_excluding_tax.amount assign='effective_tax_rate'}
{math equation='abs(round(a)-a)' a=$effective_tax_rate assign='rounding_delta'}
{if $rounding_delta < 0.09}
{math equation='round(a)' a=$effective_tax_rate assign='effective_tax_rate_rounded'}
{else}
{math equation='a' a=$effective_tax_rate assign='effective_tax_rate_rounded' format="%.1f"}
{/if}
<span class="effective-tax-rate">({$effective_tax_rate_rounded|escape:'javascript':'UTF-8'}%)</span>
{/if}
</div>
<span class="value">{$cart.subtotals.tax.value|escape:'javascript':'UTF-8'}</span>
</div>
{/if}
{* tax is set and non-zero cart summary, we show Total (tax incl.) *}
<div class="cart-summary-line cart-total cart-total-tax-included{$waitForShippingCls}">
<span class="label">{$cart.totals.total_including_tax.label}</span>
<span class="value">{$cart.totals.total_including_tax.value}</span>
<div class="cart-summary-line cart-total cart-total-tax-included{$waitForShippingCls|escape:'javascript':'UTF-8'}">
<span class="label">{$cart.totals.total_including_tax.label|escape:'htmlall':'UTF-8'}</span>
<span class="value">{$cart.totals.total_including_tax.value|escape:'htmlall':'UTF-8'}</span>
</div>
{else}
{* tax is zero or not used in cart summary, we show Total (tax_label) *}
<div class="cart-summary-line cart-total cart-total-auto-tax{$waitForShippingCls}">
<span class="label">{$cart.totals.total.label} {if isset($configuration) && $configuration.taxes_enabled}{$cart.labels.tax_short}{/if}</span>
<span class="value">{$cart.totals.total.value}</span>
<div class="cart-summary-line cart-total cart-total-auto-tax{$waitForShippingCls|escape:'javascript':'UTF-8'}">
<span class="label">{$cart.totals.total.label|escape:'htmlall':'UTF-8'}{if isset($configuration) && $configuration.taxes_enabled}<span class="tax-lbl"> {$cart.labels.tax_short|escape:'htmlall':'UTF-8'}</span>{/if}</span>
<span class="value">{$cart.totals.total.value|escape:'htmlall':'UTF-8'}</span>
</div>
{if isset($cart.subtotals.tax)}
<div class="cart-summary-line cart-total-tax{$waitForShippingCls}">
<span class="label">{$cart.subtotals.tax.label}</span>
<span class="value">{$cart.subtotals.tax.value}</span>
<div class="cart-summary-line cart-total-tax{$waitForShippingCls|escape:'javascript':'UTF-8'}">
<div class="label" style="display: inline">{$cart.subtotals.tax.label|escape:'javascript':'UTF-8'}
<span class="effective-tax-rate">(0%)</span>
</div>
<span class="value">{$cart.subtotals.tax.value|escape:'javascript':'UTF-8'}</span>
</div>
{/if}
{/if}
{if $cart.totals.total_excluding_tax.amount == $cart.totals.total.amount && $configuration.taxes_enabled}
<div style="display: none;" class="cart-summary-line vat-exempt">
<span class="label">{l s='Your order is now 0% VAT' mod='thecheckout'}</span>
</div>
{/if}
{assign var='ps_freeshipping_price' value=Configuration::get('PS_SHIPPING_FREE_PRICE')}
@@ -97,10 +117,10 @@
{math equation='a-b' a=$ps_freeshipping_price b=$total_without_shipping assign='remaining_to_spend'}
{math equation='(100*a)/b' a=$total_without_shipping b=$ps_freeshipping_price assign='completed_percentage'}
{if $remaining_to_spend > 0}
<div class="remaining-amount-to-free-shipping-container">
<div class="remaining-amount-to-free-shipping-container{if isset($cart.subtotals) && isset($cart.subtotals.shipping) && isset($cart.subtotals.shipping.amount) && $cart.subtotals.shipping.amount == 0} free{/if}">
<div class="remaining-amount-msg">{l s='Remaining amount to get free shipping: ' mod='thecheckout'} <span class="remaining-amount">{Tools::displayPrice($remaining_to_spend,$currency)}</span></div>
<div class="remaining-amount-progress">
<div class="inside-bar" style="width: {$completed_percentage}%"></div>
<div class="inside-bar" style="width: {$completed_percentage|escape:'javascript':'UTF-8'}%"></div>
</div>
</div>
{/if}

View File

@@ -22,7 +22,8 @@
* International Registered Trademark & Property of PrestaShop SA
*}
{block name='cart_detailed_product'}
<div class="cart-overview js-cart" data-refresh-url="{url entity='cart' params=['ajax' => true, 'action' => 'refresh']}">
<!-- <div class="cart-overview js-cart" data-refresh-url="{url entity='cart' params=['ajax' => true, 'action' => 'refresh']}"> -->
<div class="cart-overview js-cart">
{if $cart.products}
<ul class="cart-items">
{foreach from=$cart.products item=product}

View File

@@ -30,10 +30,10 @@
<ul class="promo-name card-block">
{foreach from=$cart.vouchers.added item=voucher}
<li class="cart-summary-line">
<span class="label">{$voucher.name}</span>
<a href="{$voucher.delete_url}" data-discount-id="{$voucher.id_cart_rule}" data-link-action="x-remove-voucher"><span class="icon-delete"></span></a>
<span class="label">{$voucher.name|escape:'htmlall':'UTF-8'}</span>
<a href="{$voucher.delete_url|escape:'javascript':'UTF-8'}" data-discount-id="{$voucher.id_cart_rule|escape:'javascript':'UTF-8'}" data-link-action="x-remove-voucher"><span class="icon-delete"></span></a>
<div class="float-xs-right">
{$voucher.reduction_formatted}
{$voucher.reduction_formatted|escape:'htmlall':'UTF-8'}
</div>
</li>
{/foreach}
@@ -41,20 +41,20 @@
{/block}
{/if}
<p class="{if $cart.discounts|count > 0}hidden{/if}">
<a class="collapse-button promo-code-button" data-bs-toggle="collapse" data-bs-target="#promo-code" data-toggle="collapse" href="#promo-code" aria-expanded="false" aria-controls="promo-code">
<p class="{if $cart.discounts|count > 0}hidden because-have-highlighted-discounts{/if}">
<a class="collapse-button promo-code-button collapsed" data-bs-toggle="collapse" data-bs-target="#promo-code" data-toggle="collapse" href="#promo-code" aria-expanded="false" aria-controls="promo-code">
{l s='Have a promo code?' d='Shop.Theme.Checkout'}
</a>
</p>
<div class="promo-code collapse{if $cart.discounts|count > 0} in{/if}" id="promo-code">
<div class="promo-code collapse{if $cart.discounts|count > 0} in show{/if}" id="promo-code">
{block name='cart_voucher_form'}
<form method="post">
<input type="hidden" name="token" value="{$static_token}">
<input type="hidden" name="token" value="{$static_token|escape:'javascript':'UTF-8'}">
<input type="hidden" name="addDiscount" value="1">
<div class="promo-input-button d-f">
<input class="promo-input" type="text" name="discount_name" placeholder="{l s='Promo code' d='Shop.Theme.Checkout'}">
<button data-link-action="x-add-voucher" type="submit" class="btn btn-primary"><span>Dodaj</span></button>
<button data-link-action="x-add-voucher" type="submit" class="btn btn-primary"><span>{l s='Add' d='Shop.Theme.Actions'}</span></button>
</div>
</form>
{/block}
@@ -73,7 +73,7 @@
<ul class="js-discount card-block promo-discounts">
{foreach from=$cart.discounts item=discount}
<li class="cart-summary-line">
<span class="label"><span class="code">{$discount.code}</span> - {$discount.name}</span>
<span class="label"><span class="code">{$discount.code|escape:'htmlall':'UTF-8'}</span> - {$discount.name|escape:'htmlall':'UTF-8'}</span>
</li>
{/foreach}
</ul>

View File

@@ -24,7 +24,7 @@
{if $field.type == 'hidden'}
{block name='form_field_item_hidden'}
<input type="hidden" class="orig-field" name="{$field.name}" value="{$field.value}">
<input type="hidden" class="orig-field" name="{$field.name|escape:'javascript':'UTF-8'}" value="{$field.value|escape:'javascript':'UTF-8'}">
{/block}
{else}
@@ -32,7 +32,7 @@
{assign var="passwordShallBeVisible" value=false} {* default value, which we may change below *}
{assign var="class" value="{if (true == $field.live)} live{/if}"}
{if $field.type === 'password' && isset($parentTplName) && $parentTplName === 'account'}
{assign var=show_create_account_checkbox value=$ps_config.PS_GUEST_CHECKOUT_ENABLED && $tc_config->create_account_checkbox && (!$customer.is_logged || $customer.is_guest)}
{assign var=show_create_account_checkbox value=$ps_config.PS_GUEST_CHECKOUT_ENABLED && $z_tc_config->create_account_checkbox && (!$customer.is_logged || $customer.is_guest)}
{if $show_create_account_checkbox}
{assign var="passwordShallBeVisible" value=(isset($opc_form_checkboxes['create-account']) && 'true' == $opc_form_checkboxes['create-account'])}
<div id="create_account" class="form-group checkbox">
@@ -57,21 +57,21 @@
{capture name="form_group_classes"}
form-group
{$field.name}
{$field.name|escape:'htmlall':'UTF-8'}
{if isset($checkoutSection) && ('invoice' === $checkoutSection || 'delivery' === $checkoutSection) && in_array($field.name, $businessFieldsList)}business-field{/if}
{if isset($checkoutSection) && ('invoice' === $checkoutSection || 'delivery' === $checkoutSection) && in_array($field.name, $privateFieldsList)}private-field{/if}
{if isset($checkoutSection) && ('invoice' === $checkoutSection || 'delivery' === $checkoutSection) && in_array($field.name, $businessDisabledFieldsList)}business-disabled-field{/if}
{$field.type}
{$field.type|escape:'htmlall':'UTF-8'}
{if (false == $field.visible) && !($field.type === 'password' && $passwordShallBeVisible)} hidden{/if}
{if !empty($field.errors)} has-error{/if}
{if $field.type === 'select' && empty($field.availableValues)} hidden{/if}
{if $field.name==='address1' && $field.value|strlen>3 && !'/\d+/'|preg_match:$field.value}missing-street-number{/if}
{if $field.css_class} {$field.css_class}{/if}
{if $field.name==='address1' && $field.value|strlen>3 && !preg_match('/\d+/',$field.value)}missing-street-number{/if}
{if $field.css_class} {$field.css_class|escape:'htmlall':'UTF-8'}{/if}
{/capture}
<div
class="{$smarty.capture.form_group_classes|strip|trim}"
style="flex-basis: {$field.width}%"
class="{$smarty.capture.form_group_classes|strip|trim|escape:'javascript':'UTF-8'}"
style="flex-basis: {$field.width|escape:'javascript':'UTF-8'}%"
>
{if $field.type === 'radio-buttons' || $field.type === 'checkbox' || $field.type === 'date' || $field.type === 'birthday'}
@@ -81,7 +81,7 @@
{/if}
<label class="{$effectType}{if $field.required && $field.css_class != 'need-dni'} required{/if}"
<label class="{$effectType|escape:'javascript':'UTF-8'}{if $field.required && $field.css_class != 'need-dni'} required{/if}"
{if $field.name==='address1'}data-missing-street-nr-notice="{l s='Missing street number?' mod='thecheckout'}"{/if}
>
@@ -89,11 +89,11 @@
{if $field.type === 'select'}
{block name='form_field_item_select'}
<select class="form-control orig-field form-control-select{$class}" name="{$field.name}"
<select class="form-control orig-field form-control-select{$class|escape:'javascript':'UTF-8'}" name="{$field.name|escape:'javascript':'UTF-8'}"
{if $field.required}required{/if}>
<option value disabled selected>{l s='-- please choose --' d='Shop.Forms.Labels'}</option>
{foreach from=$field.availableValues key="value" item="label"}
<option value="{$value}" {if $value eq $field.value} selected {/if}>{$label}</option>
<option value="{$value|escape:'javascript':'UTF-8'}" {if $value eq $field.value} selected {/if}>{$label|escape:'htmlall':'UTF-8'}</option>
{/foreach}
</select>
{/block}
@@ -102,20 +102,20 @@
{block name='form_field_item_country'}
<select
class="form-control orig-field form-control-select js-country{$class}"
name="{$field.name}"
class="form-control orig-field form-control-select js-country{$class|escape:'javascript':'UTF-8'}"
name="{$field.name|escape:'javascript':'UTF-8'}"
{if $field.required}required{/if}
>
<option value disabled selected>{l s='-- please choose --' d='Shop.Forms.Labels'}</option>
{foreach from=$field.availableValues key="option_value" item="label"}
{if is_array($label)}
{assign var="label_label" value=$label.label}
{assign var="option_data" value=$label.option_data}
{assign var="label_label" value=$label.label|escape:'javascript':'UTF-8'}
{assign var="option_data" value=$label.option_data|escape:'javascript':'UTF-8'}
{else}
{assign var="label_label" value=$label}
{assign var="option_data" value=""}
{/if}
<option {$option_data} value="{$option_value}" {if $option_value eq $field.value} selected {/if}>{$label_label}</option>
<option {$option_data|escape:'javascript':'UTF-8'} value="{$option_value|escape:'javascript':'UTF-8'}" {if $option_value eq $field.value} selected {/if}>{$label_label|escape:'htmlall':'UTF-8'}</option>
{/foreach}
</select>
{/block}
@@ -124,23 +124,23 @@
{block name='form_field_item_radio'}
<span class="field-label">
{$field.label}
{$field.label|escape:'htmlall':'UTF-8'}
</span>
<div class="available-values {$field.name}">
<div class="available-values {$field.name|escape:'javascript':'UTF-8'}">
{foreach from=$field.availableValues item="label" key="value"}
<label class="radio-inline">
<span class="custom-radio">
<input
name="{$field.name}"
name="{$field.name|escape:'javascript':'UTF-8'}"
type="radio"
value="{$value}"
value="{$value|escape:'javascript':'UTF-8'}"
class="orig-field"
{if $field.required}required{/if}
{if $value eq $field.value} checked {/if}
>
<span></span>
</span>
{$label}
{$label|escape:'htmlall':'UTF-8'}
</label>
{/foreach}
</div>
@@ -150,7 +150,7 @@
{block name='form_field_item_checkbox'}
<span class="custom-checkbox">
<input class="orig-field" name="{$field.name}" type="checkbox" value="1"
<input class="orig-field" name="{$field.name|escape:'javascript':'UTF-8'}" type="checkbox" value="1"
{if $field.value}checked="checked"{/if} {if $field.required}required{/if}>
<span><i class="material-icons rtl-no-flip checkbox-checked check-icon">&#xE5CA;</i></span>
{*
@@ -164,11 +164,11 @@
{elseif $field.type === 'date'}
{block name='form_field_item_date'}
<input name="{$field.name}" class="form-control orig-field" type="date" value="{$field.value}"
placeholder="{if isset($field.availableValues.placeholder)}{$field.availableValues.placeholder}{/if}">
<input name="{$field.name|escape:'javascript':'UTF-8'}" class="form-control orig-field" type="date" value="{$field.value|escape:'javascript':'UTF-8'}"
placeholder="{if isset($field.availableValues.placeholder)}{$field.availableValues.placeholder|escape:'javascript':'UTF-8'}{/if}">
{if isset($field.availableValues.comment)}
<span class="form-control-comment">
{$field.availableValues.comment}
{$field.availableValues.comment|escape:'htmlall':'UTF-8'}
</span>
{/if}
{/block}
@@ -176,11 +176,11 @@
{elseif $field.type === 'birthday'}
{block name='form_field_item_birthday'}
<div class="js-parent-focus">
{$field.label}
{$field.label|escape:'htmlall':'UTF-8'}
{html_select_date
field_order=DMY
time={$field.value}
field_array={$field.name}
time={$field.value|escape:'javascript':'UTF-8'}
field_array={$field.name|escape:'javascript':'UTF-8'}
prefix=false
reverse_years=true
field_separator='<br>'
@@ -200,7 +200,7 @@
{block name='form_field_item_password'}
<input
class="form-control orig-field"
name="{$field.name}"
name="{$field.name|escape:'javascript':'UTF-8'}"
type="password"
value=""
pattern=".{literal}{{/literal}5,{literal}}{/literal}"
@@ -213,7 +213,7 @@
{else} {* standard text inputs *}
{if $field.name === 'birthday' && isset($field.availableValues.placeholder)}
{assign var='placeholder' value="{$field.availableValues.placeholder}" }
{assign var='placeholder' value="{$field.availableValues.placeholder|escape:'javascript':'UTF-8'}" }
{else}
{assign 'placeholder' ' '}
{/if}
@@ -229,27 +229,27 @@
{* Remove call prefix from phone number - for display purposes, if prefix is shown separately *}
{* Part 1 *}
{if $tc_config->show_call_prefix && ($field.name === 'phone' || $field.name === 'phone_mobile')}
{if $z_tc_config->show_call_prefix && ($field.name === 'phone' || $field.name === 'phone_mobile')}
{assign 'callPrefix' '+'|cat:$field.custom_data['call_prefix']}
{$field.value = $field.value|replace:{$callPrefix}:''}
{$field.value = $field.value|replace:{$callPrefix|escape:'javascript':'UTF-8'}:''}
{/if}
{block name='form_field_item_other'}
<input
class="form-control orig-field{$class}"
name="{$field.name}"
type="{$field.type}"
value="{$field.value}"
placeholder="{$placeholder}"
{if $field.autoCompleteAttribute}autocomplete="{$field.autoCompleteAttribute}"{/if}
{if $field.maxLength}maxlength="{$field.maxLength}"{/if}
name="{$field.name|escape:'javascript':'UTF-8'}"
type="{$field.type|escape:'javascript':'UTF-8'}"
value="{$field.value|escape:'htmlall':'UTF-8'}"
placeholder="{$placeholder|escape:'javascript':'UTF-8'}"
{if $field.autoCompleteAttribute}autocomplete="{$field.autoCompleteAttribute|escape:'javascript':'UTF-8'}"{/if}
{if $field.maxLength}maxlength="{$field.maxLength|escape:'javascript':'UTF-8'}"{/if}
{if $field.required}required{/if}
>
{/block}
{* Part 2, displayed after input field, due to 'modern' theme, which uses placeholder shown CSS selectors *}
{if $tc_config->show_call_prefix && ($field.name === 'phone' || $field.name === 'phone_mobile')}
<span class="country-call-prefix">{$callPrefix}</span>
{if $z_tc_config->show_call_prefix && ($field.name === 'phone' || $field.name === 'phone_mobile')}
<span class="country-call-prefix">{$callPrefix|escape:'htmlall':'UTF-8'}</span>
{/if}
{/if}
@@ -259,7 +259,7 @@
{if $field.type !== 'checkbox' && $field.type !== 'radio-buttons' && $field.type !== 'birthday'}
<span class="field-label"{if !$field.required} data-optional-label="{l s='(optional)' mod='thecheckout'}"{/if}>
{$field.label}
{$field.label|escape:'htmlall':'UTF-8'}
</span>
{/if}

View File

@@ -14,33 +14,34 @@
{assign var='addressesCombobox' value=$addressesList.delivery}
{/if}
{*otherwise, addressCombobox won't be set and we won't continue*}
{if isset($addressesCombobox) && $addressesCombobox|@count > 0}
{assign var='hideAddressesSelection' value=($addressesCombobox|@count == 1 &&
(("invoice" == $addressType && $idAddressInvoice|array_key_exists:$addressesCombobox)
|| ("delivery" == $addressType && $idAddressDelivery|array_key_exists:$addressesCombobox)))}
(("invoice" == $addressType && array_key_exists($idAddressInvoice, $addressesCombobox))
|| ("delivery" == $addressType && array_key_exists($idAddressDelivery, $addressesCombobox))))}
<div class="customer-addresses{if $addressesCombobox|@count == 1} hidden-1{/if}">
{if $hideAddressesSelection}
<a class="custom-link" data-link-action="x-add-new-address">{l s='Add a new address' d='Shop.Theme.Actions'}</a>
{/if}
<div class="addresses-selection{if $hideAddressesSelection} hidden{/if}">
<span class="saved-addresses-label">{l s='Saved addresses:' mod='thecheckout'}</span>
<select class="not-extra-field" data-link-action="x-{$addressType}-addresses">
<select class="not-extra-field" data-link-action="x-{$addressType|escape:'javascript':'UTF-8'}-addresses">
{* <option value="-1">{l s='New' d='Shop.Theme.Catalog'}{l s='...' mod='thecheckout'}</option>*}
<option value="-1">{l s='Add a new address' d='Shop.Theme.Actions'}</option>
{foreach $addressesCombobox as $address}
<option value="{$address.id}"
<option value="{$address.id|escape:'javascript':'UTF-8'}"
{if "invoice" == $addressType}
{if $address.id == $idAddressInvoice && ($isInvoiceAddressPrimary || $idAddressInvoice != $idAddressDelivery )} selected{/if}
{if $address.id == $lastOrderInvoiceAddressId && $address.id != $idAddressDelivery && (!$isInvoiceAddressPrimary && $idAddressInvoice == $idAddressDelivery )} selected{/if}
{if $address.id == $idAddressDelivery && $idAddressInvoice != $idAddressDelivery} disabled{/if}
{* {if $address.id == $idAddressDelivery && $idAddressInvoice != $idAddressDelivery} disabled{/if}*}
{if $address.id == $idAddressDelivery} disabled{/if}
{else}
{if $address.id == $idAddressDelivery && (!$isInvoiceAddressPrimary || $idAddressInvoice != $idAddressDelivery )} selected{/if}
{if $address.id == $lastOrderDeliveryAddressId && $address.id != $idAddressInvoice && ($isInvoiceAddressPrimary && $idAddressInvoice == $idAddressDelivery )} selected{/if}
{if $address.id == $idAddressInvoice && $idAddressInvoice != $idAddressDelivery} disabled{/if}
{* {if $address.id == $idAddressInvoice && $idAddressInvoice != $idAddressDelivery} disabled{/if}*}
{if $address.id == $idAddressInvoice} disabled{/if}
{/if}
>{$address.alias}</option>
>{$address.alias|escape:'htmlall':'UTF-8'}{* /id-this:{$address.id}-idInv:{$idAddressInvoice}-idDlv:{$idAddressDelivery}*}</option>
{/foreach}
<option value="-1">{l s='Add a new address' d='Shop.Theme.Actions'}</option>
</select>
</div>
</div>

View File

@@ -10,24 +10,45 @@
{literal}
<script async
src="https://maps.googleapis.com/maps/api/js?key={/literal}{$tc_config->google_maps_api_key}{literal}&libraries=places&callback=googlePlacesScriptLoadCallback">
src="https://maps.googleapis.com/maps/api/js?key={/literal}{$z_tc_config->google_maps_api_key|escape:'javascript':'UTF-8'}{literal}&libraries=places&loading=async&callback=googlePlacesScriptLoadCallbackOnce">
</script>
<script>
function tc_reInitGooglePlaces() {
googlePlacesScriptLoadCallback();
}
var tc_autocomplete = {}
var debug_google_places = 0;
function googlePlacesScriptLoadCallback() {
if (debug_google_places == 1) {
console.log('googlePlacesScriptLoadCallback');
<script>
function googlePlacesScriptLoadCallbackOnce() {
if (typeof googlePlacesScriptLoadCallbackOnce.called === 'undefined') {
googlePlacesScriptLoadCallbackOnce.called = true;
googlePlacesScriptLoadCallback();
}
}
addEventListener('DOMContentLoaded', (event) => {
function tc_reInitGooglePlaces() {
googlePlacesScriptLoadCallback();
}
function isAddressController() {
return document.querySelector('body#address') !== null;
}
var tc_autocomplete = {}
var debug_google_places = 0;
var isoCodes = [];
try {
if (typeof tc_countriesIsoCodes !== 'undefined' && tc_countriesIsoCodes.length) {
isoCodes = JSON.parse(tc_countriesIsoCodes);
}
} catch (e) {
console.warn('Countries ISO codes parsing failed!');
}
function googlePlacesScriptLoadCallback() {
if (debug_google_places == 1) {
console.log('googlePlacesScriptLoadCallback');
}
// addEventListener('DOMContentLoaded', (event) => {
/* global google */
if (google) {
for (const tc_addr_type of ['invoice', 'delivery']) {
// console.log('Attempt to bind ' + tc_addr_type, document.querySelector(`[data-address-type=${tc_addr_type}] [name=address1]`))
tc_autocomplete[tc_addr_type] = new google.maps.places.Autocomplete(document.querySelector(`[data-address-type=${tc_addr_type}] [name=address1]`), {
if (isAddressController()) {
// When included for Prestashop's address edit controller
tc_autocomplete['address'] = new google.maps.places.Autocomplete(document.querySelector(`[name=address1]`), {
fields: ['address_components'],
strictBounds: false,
types: ['address'],
@@ -35,80 +56,182 @@
// TODO: what about US states?
// componentRestrictions: { country: ['sk'] },
});
tc_autocomplete[tc_addr_type].addListener('place_changed', () => googlePlaceChanged(tc_addr_type, tc_autocomplete[tc_addr_type].getPlace()));
tc_autocomplete['address'].addListener('place_changed', () => googlePlaceChanged('address', tc_autocomplete['address'].getPlace()));
const initialIso = $(`[data-address-type=${tc_addr_type}] [name=id_country]`).children('option').filter(':selected').attr('data-iso-code');
tc_autocomplete[tc_addr_type].setComponentRestrictions({'country': initialIso});
$('body').off('googlePlacesScriptLoadCallback').on('change.componentRestrictions', `[data-address-type=${tc_addr_type}] [name=id_country]`, function() {
console.log('Google places, change.componentRestrictions change listener called');
if (tc_autocomplete && tc_autocomplete[tc_addr_type]) {
const iso = $(this).children('option').filter(':selected').attr('data-iso-code');
if (debug_google_places == 1) {
console.log(`setting '${iso}' as component/country restriction`)
}
tc_autocomplete[tc_addr_type].setComponentRestrictions({'country': iso});
// jQuery version
// const idCountry = $(`[name=id_country]`).val();
// Vanilla JS version
const idCountry = document.querySelector(`[name=id_country]`).value;
const matchingCountry = isoCodes.find(x => x.id_country == idCountry);
if (typeof matchingCountry !== undefined && matchingCountry !== null) {
const initialIso = matchingCountry?.iso_code;
tc_autocomplete['address'].setComponentRestrictions({'country': initialIso});
}
if (typeof prestashop?.on === 'function') {
prestashop.on('updatedAddressForm', function () {
tc_reInitGooglePlaces();
})
}
} else {
// When included for TheCheckout module
for (const tc_addr_type of ['invoice', 'delivery']) {
// console.log('Attempt to bind ' + tc_addr_type, document.querySelector(`[data-address-type=${tc_addr_type}] [name=address1]`))
tc_autocomplete[tc_addr_type] = new google.maps.places.Autocomplete(document.querySelector(`[data-address-type=${tc_addr_type}] [name=address1]`), {
fields: ['address_components'],
strictBounds: false,
types: ['address'],
// TODO: component restriction based on selected country
// TODO: what about US states?
// componentRestrictions: { country: ['sk'] },
});
tc_autocomplete[tc_addr_type].addListener('place_changed', () => googlePlaceChanged(tc_addr_type, tc_autocomplete[tc_addr_type].getPlace()));
// jQuery version
// const initialIso = $(`[data-address-type=${tc_addr_type}] [name=id_country]`).children('option').filter(':selected').attr('data-iso-code');
// Vanilla JS version
const initialIso = document.querySelector(`[data-address-type=${tc_addr_type}] [name=id_country] option:checked`)?.dataset?.isoCode
if (initialIso !== undefined && initialIso !== null) {
tc_autocomplete[tc_addr_type].setComponentRestrictions({'country': initialIso});
}
});
// jQuery version
// $('body').off('googlePlacesScriptLoadCallback').on('change.componentRestrictions', `[data-address-type=${tc_addr_type}] [name=id_country]`, function() {
// // console.log('Google places, change.componentRestrictions change listener called');
// if (tc_autocomplete && tc_autocomplete[tc_addr_type]) {
// const iso = $(this).children('option').filter(':selected').attr('data-iso-code');
// if (debug_google_places == 1) {
// console.log(`setting '${iso}' as component/country restriction`)
// }
// tc_autocomplete[tc_addr_type].setComponentRestrictions({'country': iso});
// }
// });
// Vanilla JS version
document.body.addEventListener('change', function(event) {
if (event.target.matches(`[data-address-type=${tc_addr_type}] [name=id_country]`)) {
if (tc_autocomplete && tc_autocomplete[tc_addr_type]) {
const iso = event.target.querySelector('option:checked')?.dataset?.isoCode;
if (debug_google_places == 1) {
console.log(`setting '${iso}' as component/country restriction (vanilla JS)`)
}
tc_autocomplete[tc_addr_type].setComponentRestrictions({'country': iso});
}
}
});
}
}
}
});
}
// });
}
function googlePlaceChanged(addressType, place) {
if (place.address_components) {
if (debug_google_places == 1) {
console.log(addressType, place);
}
const placeDetails = place.address_components.reduce((acc, x) => ({...acc, [x.types[0]]: x.long_name}), {});
if (debug_google_places == 1) {
console.log('Place details: ', placeDetails);
}
function googlePlaceChanged(addressType, place) {
if (place.address_components) {
if (debug_google_places == 1) {
console.log(addressType, place);
}
const placeDetails = place.address_components.reduce((acc, x) => ({...acc, [x.types[0]]: x.long_name}), {});
if (debug_google_places == 1) {
console.log('Place details: ', placeDetails);
}
const streetNumberFirst = ['US', 'GB', 'AU'].includes(tc_autocomplete[addressType]?.componentRestrictions?.country);
const streetNumberFirst = ['US', 'GB', 'AU'].includes(tc_autocomplete[addressType]?.componentRestrictions?.country);
const stateFromAdministrativeArea2 = ['IT'].includes(tc_autocomplete[addressType]?.componentRestrictions?.country);
const tc_place_address = {};
if (streetNumberFirst) {
tc_place_address.street = `${placeDetails?.street_number || ''} ${placeDetails?.route || ''}`;
} else {
tc_place_address.street = `${placeDetails?.route || ''} ${placeDetails?.street_number || ''}`;
}
tc_place_address.city = placeDetails?.locality || placeDetails?.sublocality_level_1 || '';
tc_place_address.postcode = placeDetails?.postal_code || '';
tc_place_address.state = placeDetails?.administrative_area_level_1 || '';
const tc_place_address = {};
if (streetNumberFirst) {
tc_place_address.street = `${placeDetails?.street_number || placeDetails?.premise || ''} ${placeDetails?.route || ''}`;
} else {
tc_place_address.street = `${placeDetails?.route || placeDetails?.locality} ${placeDetails?.street_number || placeDetails?.premise || ''}`;
}
//
// if (streetNumberFirst) {
// tc_place_address.street = `${placeDetails?.street_number || ''} ${placeDetails?.route || ''}`;
// } else {
// tc_place_address.street = `${placeDetails?.route || ''} ${placeDetails?.street_number || ''}`;
// }
tc_place_address.city = placeDetails?.locality || placeDetails?.sublocality_level_1 || '';
tc_place_address.postcode = placeDetails?.postal_code || '';
if (debug_google_places == 1) {
console.log(tc_place_address);
}
if (stateFromAdministrativeArea2) {
var provincia = placeDetails?.administrative_area_level_2 || placeDetails?.administrative_area_level_1 || '';
tc_place_address.state = provincia.replace(/^.*? di /, '');
} else {
tc_place_address.state = placeDetails?.administrative_area_level_1 || '';
}
var mapPlacePropsToFields = {
address1: 'street',
city: 'city',
postcode: 'postcode',
id_state: 'state'
}
if (debug_google_places == 1) {
console.log(tc_place_address);
}
var el;
var stateEl;
for (const [fieldName, propName] of Object.entries(mapPlacePropsToFields)) {
el = $(`[data-address-type=${addressType}] [name=${fieldName}]`);
if (tc_place_address && tc_place_address[propName]) {
if (propName === 'state') {
stateEl = el.find('option').filter(function() {
return $.trim($(this).text()).toLowerCase() === (tc_place_address[propName] || '').toLowerCase();
});
if (stateEl && stateEl.length) {
stateEl.attr('selected', true).trigger('change');
}
var mapPlacePropsToFields = {
address1: 'street',
city: 'city',
postcode: 'postcode',
id_state: 'state'
}
var el;
var stateEl;
for (const [fieldName, propName] of Object.entries(mapPlacePropsToFields)) {
// jQuery version
// if (isAddressController()) {
// el = $(`[name=${fieldName}]`);
// } else {
// el = $(`[data-address-type=${addressType}] [name=${fieldName}]`);
// }
// if (tc_place_address && tc_place_address[propName]) {
// if (propName === 'state') {
// stateEl = el.find('option').filter(function() {
// return $.trim($(this).text()).toLowerCase().replace(/[^a-z]/g,'') === (tc_place_address[propName] || '').toLowerCase().replace(/[^a-z]/g,'');
// });
// if (stateEl && stateEl.length) {
// stateEl.attr('selected', true).trigger('change');
// }
// } else {
// el.val(tc_place_address[propName] || '');
// setTimeout(function (thisEl) {
// // console.log('el.val', thisEl.val())
// thisEl.change();
// }, 100, el);
// }
// }
// Vanilla JS version
if (isAddressController()) {
el = document.querySelector(`[name=${fieldName}]`);
} else {
el.val(tc_place_address[propName] || '');
setTimeout(function (thisEl) {
// console.log('el.val', thisEl.val())
thisEl.change();
}, 100, el);
el = document.querySelector(`[data-address-type=${addressType}] [name=${fieldName}]`);
}
if (tc_place_address && tc_place_address[propName] && el) {
if (propName === 'state') {
stateEl = el.querySelector('option:checked');
stateEl = Array.from(el.querySelectorAll('option')).filter(x =>
x.innerText.trim().toLowerCase().replace(/[^a-z]/g, '') === (tc_place_address[propName] || '').toLowerCase().replace(/[^a-z]/g, ''));
if (stateEl && stateEl.length) {
stateEl[0].selected = true;
stateEl[0].dispatchEvent(new Event('change'));
}
} else {
el.value = tc_place_address[propName] || '';
setTimeout(function (thisEl) {
// console.log('el.val', thisEl.val())
// Prefer jquery call so that attached event handlers are properly executed
if (typeof $ === 'function' && typeof $(thisEl) !== 'undefined' && typeof $(thisEl).change === 'function') {
$(thisEl).change();
} else {
thisEl.dispatchEvent(new Event('change'));
}
}, 100, el);
}
}
}
}
}
}
</script>
{/literal}
</script>
{/literal}

View File

@@ -10,7 +10,7 @@
<div id="payment-confirmation">
<div class="ps-shown-by-js">
<button type="submit" class="btn btn-primary center-block">
{l s='Pay' mod='thecheckout'} <span class="pay-amount">{$cart.totals.total_including_tax.value}</span>
{l s='Pay' mod='thecheckout'} <span class="pay-amount">{$cart.totals.total_including_tax.value|escape:'htmlall':'UTF-8'}</span>
</button>
</div>
</div>

View File

@@ -7,9 +7,9 @@
* @author Peter Sliacky (Zelarg)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*}
{assign secure_url $secure_protocol|cat:'/'|cat:'/'|cat:$tc_config->author}
{assign product_path $tc_config->trial_tld|cat:$tc_config->trial_lang|cat:$tc_config->trial_prod_id|cat:$tc_config->trial_prod_name}
{assign secure_url $secure_protocol|cat:'/'|cat:'/'|cat:$z_tc_config->author}
{assign product_path $z_tc_config->trial_tld|cat:$z_tc_config->trial_lang|cat:$z_tc_config->trial_prod_id|cat:$z_tc_config->trial_prod_name}
<div id="tc_secure_notice" style="display:none;"> {*Visible only in trial mode, otherwise hidden*}
<a href="{$secure_url}.{$tc_config->trial_tld}"
target="_blank"{if 0==$url_len%4} rel="nofollow"{/if}>{if 0==$url_len%7}{$secure_url}.{$tc_config->trial_tld}{elseif 0==$url_len%2}{$tc_config->author|capitalize}{else}{$tc_config->author}.{$tc_config->trial_tld}{/if}</a>
<a href="{$secure_url|escape:'javascript':'UTF-8'}.{$z_tc_config->trial_tld|escape:'javascript':'UTF-8'}"
target="_blank"{if 0==$url_len%4} rel="nofollow"{/if}>{if 0==$url_len%7}{$secure_url|escape:'javascript':'UTF-8'}.{$z_tc_config->trial_tld|escape:'javascript':'UTF-8'}{elseif 0==$url_len%2}{$z_tc_config->author|capitalize|escape:'javascript':'UTF-8'}{else}{$z_tc_config->author|escape:'javascript':'UTF-8'}.{$z_tc_config->trial_tld|escape:'javascript':'UTF-8'}{/if}</a>
</div>

View File

@@ -9,15 +9,15 @@
*}
<style>
/* BEGIN Custom CSS styles from config page */
{$tc_config->custom_css nofilter}
{$z_tc_config->custom_css nofilter}
/* END Custom CSS styles from config page */
</style>
<script>
/* BEGIN Custom JS code from config page */
{$tc_config->custom_js nofilter}
{$z_tc_config->custom_js nofilter}
/* END Custom JS code from config page */
var amazon_ongoing_session = ("{$amazon_ongoing_session}" == "1");
var amazon_ongoing_session = ("{$amazon_ongoing_session|escape:'javascript':'UTF-8'}" == "1");
</script>
<div style="display: none;">
{* Inner container will be taken out by JS in separate-payment.js *}
@@ -25,7 +25,7 @@
<div class="customer-block-container">
<div id="customer-block">
{$customer.firstname} {$customer.lastname} - {$customer.email}
{$customer.firstname|escape:'htmlall':'UTF-8'} {$customer.lastname|escape:'htmlall':'UTF-8'} - {$customer.email|escape:'htmlall':'UTF-8'}
</div>
</div>
@@ -46,22 +46,24 @@
<div id="shipping-method">
<span class="shipping-method-header">{l s='Shipping Method' d='Shop.Theme.Checkout'}</span>
{if $shipping_logo}
<img src="{$shipping_logo}" />
<img src="{$shipping_logo|escape:'javascript':'UTF-8'}" />
{/if}
{$shipping_method->name} - {$shipping_method->delay[$language.id]}
{$shipping_method->name|escape:'htmlall':'UTF-8'} - {$shipping_method->delay[$language.id]|escape:'htmlall':'UTF-8'}
</div>
{if $delivery_message}
<div id="delivery-message">
<span class="delivery-message-header">{l s='Message' d='Shop.Forms.Labels'}</span>
{$delivery_message}
{$delivery_message|escape:'htmlall':'UTF-8'}
</div>
{/if}
</div>
<div id="edit-button-block">
<button id="x-checkout-edit" data-href="{$urls.pages.order}" class="btn btn-primary">{l s='Edit' d='Shop.Theme.Actions'}</button>
<button id="x-checkout-edit" data-href="{$urls.pages.order|escape:'javascript':'UTF-8'}" class="btn btn-primary">{l s='Edit' d='Shop.Theme.Actions'}</button>
</div>
<div class="layout-right html_box_4" style="display: none;">
{$z_tc_config->html_box_4 nofilter}
</div>
</section>
</div>

View File

@@ -13,7 +13,7 @@
function tc_fbAsyncInit() {
window.fbAsyncInit = function () {
FB.init({
appId: '{/literal}{$tc_config->social_login_fb_app_id}{literal}',
appId: '{/literal}{$z_tc_config->social_login_fb_app_id|escape:'javascript':'UTF-8'}{literal}',
cookie: true,
xfbml: true,
oauth: true,
@@ -28,7 +28,7 @@
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "https://connect.facebook.net/{/literal}{$iso}{literal}/sdk.js";
js.src = "https://connect.facebook.net/{/literal}{$iso|escape:'javascript':'UTF-8'}{literal}/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
}
@@ -39,6 +39,7 @@
// window.addEventListener('DOMContentLoaded', tc_fbAsyncInit);
// }
window.addEventListener('DOMContentLoaded', tc_fbAsyncInit);
// $(document).ready(tc_fbAsyncInit);
</script>
{/literal}

View File

@@ -15,7 +15,7 @@
var attemptsLeft = 15;
function tc_initGoogleWithDelay() {
if ('undefined' !== typeof tc_googleLogin) {
tc_googleLogin.init('{/literal}{$tc_config->social_login_google_client_id}{literal}');
tc_googleLogin.init('{/literal}{$z_tc_config->social_login_google_client_id|escape:'javascript':'UTF-8'}{literal}');
} else if (attemptsLeft-- > 0) {
// console.log('attempt: ' + (15-attemptsLeft));
setTimeout(tc_initGoogleWithDelay, 300);

View File

@@ -9,10 +9,10 @@
*}
<div id="static-customer-info-container">
{if !$s_customer.is_guest && $s_customer.is_logged}
<a class="edit-customer-info" href="{$urls.pages.identity}">
<a class="edit-customer-info" href="{$urls.pages.identity|escape:'javascript':'UTF-8'}">
<div class="static-customer-info" data-edit-label="{l s='Edit' d='Shop.Theme.Actions'}">
<div class="customer-name">{$s_customer.firstname} {$s_customer.lastname}</div>
<div class="customer-email">{$s_customer.email}</div>
<div class="customer-name">{$s_customer.firstname|escape:'htmlall':'UTF-8'} {$s_customer.lastname|escape:'htmlall':'UTF-8'}</div>
<div class="customer-email">{$s_customer.email|escape:'htmlall':'UTF-8'}</div>
</div>
</a>
{/if}