- 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
2156 lines
99 KiB
PHP
2156 lines
99 KiB
PHP
<?php
|
|
/**
|
|
* NOTICE OF LICENSE
|
|
*
|
|
* This source file is subject to the Software License Agreement
|
|
* that is bundled with this package in the file LICENSE.txt.
|
|
*
|
|
* @author Peter Sliacky (Zelarg)
|
|
* @copyright Peter Sliacky (Zelarg)
|
|
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
|
*/
|
|
|
|
if (!defined('_PS_VERSION_')) {
|
|
exit;
|
|
}
|
|
|
|
use Monolog\Logger;
|
|
use Monolog\Handler\StreamHandler;
|
|
use Monolog\Handler\BrowserConsoleHandler;
|
|
use Monolog\Processor\IntrospectionProcessor;
|
|
use Monolog\Processor\WebProcessor;
|
|
use Monolog\Handler\ChromePHPHandler;
|
|
use module\thecheckout\Config;
|
|
use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter;
|
|
use PrestaShop\PrestaShop\Adapter\ObjectPresenter;
|
|
|
|
class TheCheckout extends Module
|
|
{
|
|
|
|
/**
|
|
* @var array $module_settings An array of settings provided on configuration page
|
|
*/
|
|
// public $conf_prefix = "opc_"; // not used anymore, prefix is fixed to 'tc_'
|
|
/**
|
|
* @var Config
|
|
*/
|
|
public $config;
|
|
public $debug = false;
|
|
public $deepDebug = false;
|
|
public $debugJsController = false;
|
|
private $logger;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->name = 'thecheckout';
|
|
$this->tab = 'checkout';
|
|
$this->version = '3.3.10';
|
|
$this->author = 'PrestaDev.pl';
|
|
$this->module_key = "2e602e0a1021555e3d85311cd8ef756d1";
|
|
//$this->moduleTHECHECKOUT_key = "2e602e0a1021555e3d85311cd8ef756d";
|
|
//$this->moduleOPC_key = "38254238bedae1ccc492a65148109fdd";
|
|
|
|
$this->need_instance = 0;
|
|
$this->ps_versions_compliancy = array('min' => '1.7', 'max' => '9.1');
|
|
$this->bootstrap = true;
|
|
|
|
parent::__construct(); // The parent construct is required for translations
|
|
|
|
$this->page = basename(__FILE__, '.php');
|
|
$this->displayName = $this->l('The Checkout');
|
|
$this->description = $this->l('Powerful and intuitive checkout process.');
|
|
$this->confirmUninstall = $this->l('Are you sure you want to uninstall?');
|
|
|
|
$this->controllers = array('front');
|
|
|
|
$this->initTheCheckout();
|
|
}
|
|
|
|
public function initPsKernel() {
|
|
// Uncomment if kernel is necessary for e.g. shipping modules
|
|
// global $kernel;
|
|
// if(!$kernel){
|
|
// require_once _PS_ROOT_DIR_.'/app/AppKernel.php';
|
|
// $kernel = new \AppKernel(_PS_MODE_DEV_ ? 'dev' : 'prod', _PS_MODE_DEV_);
|
|
// $kernel->boot();
|
|
// }
|
|
}
|
|
|
|
private function checkStripeNeedPatch()
|
|
{
|
|
return false; // Since checkout module v2.3.4, patch in Stripe is no more required.
|
|
//
|
|
// $needPatch = false;
|
|
// $stripeModuleName = 'stripe_official';
|
|
// if (Module::isInstalled($stripeModuleName) && Module::isEnabled($stripeModuleName)) {
|
|
// $stripe_official_class = _PS_MODULE_DIR_ . "$stripeModuleName/$stripeModuleName.php";
|
|
// if (file_exists($stripe_official_class)) {
|
|
// $file_content = Tools::file_get_contents($stripe_official_class);
|
|
// $needPatch = !(preg_match('/module-thecheckout-order/', $file_content) > 0);
|
|
// }
|
|
// }
|
|
// return $needPatch;
|
|
}
|
|
|
|
private function checkBraintreeNeedsPatch()
|
|
{
|
|
$needPatch = false;
|
|
$braintreeModuleName = 'braintreeofficial';
|
|
if (Module::isInstalled($braintreeModuleName) && Module::isEnabled($braintreeModuleName)) {
|
|
$braintree_class = _PS_MODULE_DIR_ . "$braintreeModuleName/views/js/payment_bt.js";
|
|
if (file_exists($braintree_class)) {
|
|
$file_content = Tools::file_get_contents($braintree_class);
|
|
$needPatch = !(preg_match('/braintree-thecheckout-fix/', $file_content) > 0);
|
|
}
|
|
}
|
|
return $needPatch;
|
|
}
|
|
|
|
private function checkMondialNeedPatch()
|
|
{
|
|
return false; // no need to check since mondialrelay v3.1.8
|
|
// $needPatch = false;
|
|
// $moduleName = 'mondialrelay';
|
|
// if (Module::isInstalled($moduleName) && Module::isEnabled($moduleName)) {
|
|
// $moduleClass = _PS_MODULE_DIR_ . "$moduleName/views/js/front/checkout/checkout-17.js";
|
|
// if (file_exists($moduleClass)) {
|
|
// $file_content = Tools::file_get_contents($moduleClass);
|
|
// $needPatch = !(preg_match('/thecheckout-patched/', $file_content) > 0);
|
|
// }
|
|
// }
|
|
// return $needPatch;
|
|
}
|
|
|
|
private function checkAmcPsShipItNeedPatch()
|
|
{
|
|
$needPatch = false;
|
|
$moduleName = 'amcpsshipit';
|
|
if (Module::isInstalled($moduleName) && Module::isEnabled($moduleName)) {
|
|
$moduleClass = _PS_MODULE_DIR_ . "$moduleName/amcpsshipit.php";
|
|
if (file_exists($moduleClass)) {
|
|
$file_content = Tools::file_get_contents($moduleClass);
|
|
$needPatch = !(preg_match('/thecheckout-patched/', $file_content) > 0);
|
|
}
|
|
}
|
|
return $needPatch;
|
|
}
|
|
|
|
private function checkInstallation()
|
|
{
|
|
if (Tools::getIsset('reinstallhooks')) {
|
|
$this->registerHooks();
|
|
Configuration::updateValue('install_date', date("m/d/y"));
|
|
return 'ok, hooks reinstalled';
|
|
}
|
|
|
|
if (Tools::getIsset('resetsubconfig')) {
|
|
$tc_options = $this->config->getAllOptions('TC_', true);
|
|
$tc_options_list = '("' . join('","', array_keys($tc_options)) . '")';
|
|
|
|
@Db::getInstance(_PS_USE_SQL_SLAVE_)->execute('DELETE FROM ' . _DB_PREFIX_ . 'configuration where (id_shop_group is not null or id_shop is not null) and name in ' . $tc_options_list);
|
|
|
|
return 'ok, sub-shops config for TheCheckout is re-set';
|
|
}
|
|
|
|
if ($this->checkStripeNeedPatch()) {
|
|
return 'Detected '.$this->tagIt('b', 'stripe_official').' payment module - it '.$this->tagIt('b', 'requires a patch').' to work properly with
|
|
TheCheckout, please contact us for more details or check our blog';
|
|
}
|
|
|
|
if ($this->checkMondialNeedPatch()) {
|
|
return 'Detected '.$this->tagIt('b', 'mondialrelay').' shipping module - it '.$this->tagIt('b', 'requires a patch').' to work properly with
|
|
TheCheckout, please contact us for more details or check our blog';
|
|
}
|
|
|
|
if ($this->checkAmcPsShipItNeedPatch()) {
|
|
return 'Detected '.$this->tagIt('b', 'amcpsshipit').' shipping module - it '.$this->tagIt('b', 'requires a patch').' to work properly with
|
|
TheCheckout, please update amcpsshipit.php and extend condition if ($controllerClass !== \'OrderController\') with
|
|
&& $controllerClass !== \'TheCheckoutModuleFrontController\' and add this comment (thecheckout-patched) to remove this message';
|
|
}
|
|
|
|
// $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('SELECT * FROM '. _DB_PREFIX_ .'required_field');
|
|
// print_r($result); exit;
|
|
|
|
// Check common options and permissions
|
|
$writePermissions = array(
|
|
_PS_MODULE_DIR_ . $this->name . '/log/',
|
|
_PS_MODULE_DIR_ . $this->name . '/views/css/',
|
|
);
|
|
$permissionsError = '[permissions error] ';
|
|
|
|
foreach ($writePermissions as $file) {
|
|
if (!is_writable($file)) {
|
|
return "$permissionsError: $file is not writable!";
|
|
}
|
|
}
|
|
|
|
// Check hooks
|
|
$hooksList = array('actionDispatcher', 'displayOrderConfirmation', 'displayBackOfficeHeader');
|
|
foreach ($hooksList as $hookName) {
|
|
if (!$this->isRegisteredInHook($hookName)) {
|
|
return "[hook error] Missing hook registration for $hookName! Please add to URL: &reinstallhooks";
|
|
}
|
|
}
|
|
|
|
// Check DB required fields (Customer and Address objects)
|
|
$tmpCustomer = new Customer();
|
|
$requiredFields = $tmpCustomer->getFieldsRequiredDatabase();
|
|
foreach ($requiredFields as $field) {
|
|
return "[required fields error] " . $field['object_name'] . ':' . $field['field_name'];
|
|
}
|
|
if (class_exists('CustomerAddress')) {
|
|
$tmpAddress = new CustomerAddress();
|
|
$requiredFields = $tmpAddress->getFieldsRequiredDatabase();
|
|
foreach ($requiredFields as $field) {
|
|
return "[required fields error] " . $field['object_name'] . ':' . $field['field_name'];
|
|
}
|
|
}
|
|
// Legacy Address object
|
|
if (class_exists('Address')) {
|
|
$tmpAddress = new Address();
|
|
$requiredFields = $tmpAddress->getFieldsRequiredDatabase();
|
|
foreach ($requiredFields as $field) {
|
|
return "[required fields error (legacy Address object)] " . $field['object_name'] . ':' . $field['field_name'];
|
|
}
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
private function initTheCheckout()
|
|
{
|
|
if (null == $this->config) {
|
|
$this->setupLogger();
|
|
$this->setConfigOptions();
|
|
}
|
|
}
|
|
|
|
public function includeDependency($path)
|
|
{
|
|
if (file_exists(_PS_MODULE_DIR_ . $this->name . '/' . $path)) {
|
|
include_once(_PS_MODULE_DIR_ . $this->name . '/' . $path);
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public function getTranslation($key)
|
|
{
|
|
// These comments are required here, so that PS core translation parser could offer them in
|
|
// BO / International / Translations / Module translations
|
|
|
|
// $this->l('Extra field No.1');
|
|
// $this->l('Extra field No.2');
|
|
// $this->l('Extra field No.3');
|
|
// $this->l('Extra field No.4');
|
|
// $this->l('Extra field No.5');
|
|
// $this->l('Payment fee');
|
|
// $this->l('Required Checkbox No.1');
|
|
// $this->l('Required Checkbox No.2');
|
|
// $this->l('SDI');
|
|
// $this->l('PEC');
|
|
// $this->l('PA');
|
|
// $this->l('Invalid DNI');
|
|
// $this->l('Probably a typo? Please try again.');
|
|
// $this->l('You already have an account with us. Sign in or continue as guest.');
|
|
// $this->l('Apple Pay');
|
|
return $this->l($key);
|
|
}
|
|
|
|
public function tagIt($tag, $content = '', $attr = '') {
|
|
$lt = '<';
|
|
$gt = '>';
|
|
$single = in_array($tag, ['br', 'input']);
|
|
$open = $lt.$tag.' '.$attr.$gt;
|
|
$close = $single ? '' : $lt.'/'.$tag.$gt;
|
|
$content = $single ? '' : $content;
|
|
return $open.$content.$close;
|
|
}
|
|
|
|
private function setConfigOptions()
|
|
{
|
|
$this->includeDependency('classes/Config.php');
|
|
$this->config = new Config();
|
|
}
|
|
|
|
private function setupLogger()
|
|
{
|
|
$this->logger = new Logger(get_class($this));
|
|
|
|
if (is_writable(_PS_MODULE_DIR_ . $this->name . '/log/')) {
|
|
$this->logger->pushHandler(
|
|
new StreamHandler(
|
|
_PS_MODULE_DIR_ . $this->name . '/log/debug.log',
|
|
($this->debug) ? Logger::DEBUG : Logger::WARNING
|
|
)
|
|
);
|
|
}
|
|
|
|
// Line formatter without empty brackets in the end
|
|
//$formatter = new LineFormatter(null, null, false, true);
|
|
//$debugHandler->setFormatter($formatter);
|
|
|
|
if ($this->debug) {
|
|
$this->logger->pushHandler(
|
|
new ChromePHPHandler(Logger::DEBUG)
|
|
);
|
|
$this->logger->pushProcessor(new WebProcessor());
|
|
}
|
|
if ($this->debug && $this->deepDebug) {
|
|
$this->logger->pushProcessor(
|
|
new IntrospectionProcessor(Logger::DEBUG, array(), 1) // 1=skip top-most level in stack
|
|
);
|
|
$self = $this;
|
|
$this->logger->pushProcessor(function ($record) use ($self) {
|
|
$record['extra']['id_cart'] = $self->context->cart->id;
|
|
$record['extra']['id_customer'] = $self->context->cart->id_customer;
|
|
$record['extra']['id_address_delivery'] = $self->context->cart->id_address_delivery;
|
|
$record['extra']['id_address_invoice'] = $self->context->cart->id_address_invoice;
|
|
$dateObj = DateTime::createFromFormat('U.u', microtime(true));
|
|
$dateObj->setTimezone(new DateTimeZone('Europe/Amsterdam'));
|
|
$executionTime = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
|
|
$record['extra']['timestamp'] = $dateObj->format('H:i:s.') .
|
|
sprintf('%03d', floor($dateObj->format('u') / 1000)) .
|
|
sprintf(' (+%.03f)', $executionTime);
|
|
return $record;
|
|
});
|
|
}
|
|
}
|
|
|
|
public function logInfo($msg)
|
|
{
|
|
$this->logger->info($msg);
|
|
}
|
|
|
|
public function logDebug($msg)
|
|
{
|
|
$this->logger->debug($msg);
|
|
}
|
|
|
|
public function logWarning($msg)
|
|
{
|
|
$this->logger->warn($msg);
|
|
}
|
|
|
|
public function logError($msg)
|
|
{
|
|
$this->logger->error($msg);
|
|
}
|
|
|
|
private function flatten_array($input_array) {
|
|
$result = array();
|
|
array_walk_recursive($input_array, function($array, $key) use (&$result) { $result[] = $key; });
|
|
return $result;
|
|
}
|
|
|
|
private function setTagsList($key, $array_input) {
|
|
$input_json = json_encode(array_map(function ($a) { return array('id' => $a, 'title' => $a); }, array_values($array_input)));
|
|
Media::addJsDefL($key, $input_json);
|
|
}
|
|
|
|
public function hookDisplayBackOfficeHeader()
|
|
{
|
|
$controller = (string) Tools::getValue('controller');
|
|
$configure = (string) Tools::getValue('configure');
|
|
if ($controller != 'AdminModules' || $configure != 'thecheckout') {
|
|
return;
|
|
}
|
|
Media::addJsDefL('thecheckout_video_tutorial', $this->l('Tutorial'));
|
|
Media::addJsDefL('thecheckout_video_tutorial_sub1', $this->l('How to create Facebook App ID and Secret?'));
|
|
Media::addJsDefL('thecheckout_video_tutorial_sub2', $this->l('How to create Google Client ID and Secret?'));
|
|
Media::addJsDefL('thecheckout_tutorial_maps_api', $this->l('How to create Google maps API key?'));
|
|
Media::addJsDefL('thecheckout_reset_conf_for', $this->l('Reset default configuration for'));
|
|
Media::addJsDefL('thecheckout_init_html_editor', $this->l('Use HTML editor'));
|
|
|
|
$flattened = $this->flatten_array($this->config->blocks_layout);
|
|
$available_layout_blocks = array_diff( array_unique($flattened), ['size'] );
|
|
$this->setTagsList('thecheckout_available_layout_blocks', $available_layout_blocks);
|
|
|
|
$all_fields = array_keys(array_merge($this->config->invoice_fields, $this->config->delivery_fields));
|
|
$all_fields_sanitized = array_merge(array('id_country', 'id_state'), array_diff($all_fields, ['Country:name', 'State:name']));
|
|
$this->setTagsList('thecheckout_available_address_fields', $all_fields_sanitized);
|
|
}
|
|
|
|
private function registerHooks()
|
|
{
|
|
return (
|
|
$this->registerHook('actionDispatcher')
|
|
&& $this->registerHook('displayOrderConfirmation')
|
|
&& $this->registerHook('displayHeader')
|
|
&& $this->registerHook('displayBackOfficeHeader')
|
|
&& $this->registerHook('additionalCustomerFormFields')
|
|
&& $this->registerHook('displayFooterAfter')
|
|
&& $this->registerHook('actionBuildFrontEndObject')
|
|
);
|
|
}
|
|
|
|
public function install()
|
|
{
|
|
if (!parent::install() || !$this->registerHooks()
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
// Increase cache version (JS & CSS)
|
|
$css_cache_version = (int)Configuration::get('PS_CCCCSS_VERSION');
|
|
$js_cache_version = (int)Configuration::get('PS_CCCJS_VERSION');
|
|
Configuration::updateValue('PS_CCCCSS_VERSION', ($css_cache_version + 1));
|
|
Configuration::updateValue('PS_CCCJS_VERSION', ($js_cache_version + 1));
|
|
|
|
$reassurance_sample_html = array();
|
|
$existing_step_label_1 = array();
|
|
$existing_step_label_2 = array();
|
|
$existing_step_label_3 = array();
|
|
$existing_step_validation_error_3 = array();
|
|
|
|
$reassurance_samples = array(
|
|
'en' => $this->tagIt('div',
|
|
$this->tagIt('div',
|
|
$this->tagIt('span', '', 'class="icon"') .
|
|
$this->tagIt('h3', 'Security policy') . 'We use modern SSL to '. $this->tagIt('b', 'secure payment'),
|
|
'class="reassurance-section security"').
|
|
$this->tagIt('div',
|
|
$this->tagIt('span', '', 'class="icon"') .
|
|
$this->tagIt('h3', 'Delivery policy') . 'Orders made on workdays, until 13:00 are '. $this->tagIt('b', 'shipped same day') . ' (if all goods are in stock)',
|
|
'class="reassurance-section delivery"').
|
|
$this->tagIt('div',
|
|
$this->tagIt('span', '', 'class="icon"') .
|
|
$this->tagIt('h3', 'Return policy') . 'Purchases can be '. $this->tagIt('b', 'returned') . ' within 14 days, without any explanation',
|
|
'class="reassurance-section return"'),
|
|
'class="thecheckout-reassurance"').
|
|
$this->tagIt('p', '*please edit this in TheCheckout module configuration, Layout tab -> HTML Box No.1 for your language'),
|
|
'cs' => $this->tagIt('div',
|
|
$this->tagIt('div',
|
|
$this->tagIt('span', '', 'class="icon"') .
|
|
$this->tagIt('h3', 'Bezpečnostní politika') . 'Používáme moderní SSL pro '. $this->tagIt('b', 'bezpeční platbu'),
|
|
'class="reassurance-section security"').
|
|
$this->tagIt('div',
|
|
$this->tagIt('span', '', 'class="icon"') .
|
|
$this->tagIt('h3', 'Dodací podmínky') . 'Objednávky zadané v pracovní dny do 13:00 jsou '. $this->tagIt('b', 'odeslány v ten samý den') . ' (v případe, že všechno zboží je skladem)',
|
|
'class="reassurance-section delivery"').
|
|
$this->tagIt('div',
|
|
$this->tagIt('span', '', 'class="icon"') .
|
|
$this->tagIt('h3', 'Vrácení zboží') . 'Zboží můžete '. $this->tagIt('b', 'vrátit') . ' v lhůtě 14 dní bez uvedení důvodu.',
|
|
'class="reassurance-section return"'),
|
|
'class="thecheckout-reassurance"').
|
|
$this->tagIt('p', '*prosím upravte tento blok v nastavení modulu TheCheckout, záložka Rozvržení -> HTML pole č.1 pro jazyk [ Čeština (Czech) ]')
|
|
);
|
|
|
|
|
|
foreach (Language::getLanguages() as $language) {
|
|
$existingReassuranceHtml = Configuration::get('TC_html_box_1', $language['id_lang']);
|
|
if (!$existingReassuranceHtml || "" == trim($existingReassuranceHtml)) {
|
|
if (array_key_exists($language['iso_code'], $reassurance_samples)) {
|
|
$reassurance_sample_html[$language['id_lang']] = $reassurance_samples[$language['iso_code']];
|
|
} else {
|
|
$reassurance_sample_html[$language['id_lang']] = $reassurance_samples['en'];
|
|
}
|
|
} else {
|
|
$reassurance_sample_html[$language['id_lang']] = Configuration::get('TC_html_box_1',
|
|
$language['id_lang']);
|
|
}
|
|
$existing_step_label_1 = Configuration::get('TC_step_label_1', $language['id_lang']);
|
|
if (!$existing_step_label_1 || "" == trim($existing_step_label_1)) {
|
|
$step_label_1_sample[$language['id_lang']] = 'Cart';
|
|
} else {
|
|
$step_label_1_sample[$language['id_lang']] = Configuration::get('TC_step_label_1', $language['id_lang']);
|
|
}
|
|
$existing_step_label_2 = Configuration::get('TC_step_label_2', $language['id_lang']);
|
|
if (!$existing_step_label_2 || "" == trim($existing_step_label_2)) {
|
|
$step_label_2_sample[$language['id_lang']] = 'Shipping and payment';
|
|
} else {
|
|
$step_label_2_sample[$language['id_lang']] = Configuration::get('TC_step_label_2', $language['id_lang']);
|
|
}
|
|
$existing_step_label_3 = Configuration::get('TC_step_label_3', $language['id_lang']);
|
|
if (!$existing_step_label_3 || "" == trim($existing_step_label_3)) {
|
|
$step_label_3_sample[$language['id_lang']] = 'Address, confirmation';
|
|
} else {
|
|
$step_label_3_sample[$language['id_lang']] = Configuration::get('TC_step_label_3', $language['id_lang']);
|
|
}
|
|
$existing_step_validation_error_3 = Configuration::get('TC_step_validation_error_3', $language['id_lang']);
|
|
if (!$existing_step_validation_error_3 || "" == trim($existing_step_validation_error_3)) {
|
|
$step_validation_error_3_sample[$language['id_lang']] = 'Please choose delivery option.';
|
|
} else {
|
|
$step_validation_error_3_sample[$language['id_lang']] = Configuration::get('TC_step_validation_error_3', $language['id_lang']);
|
|
}
|
|
}
|
|
|
|
Configuration::updateValue('TC_html_box_1', $reassurance_sample_html, true);
|
|
Configuration::updateValue('TC_step_label_1', $step_label_1_sample, false);
|
|
Configuration::updateValue('TC_step_label_2', $step_label_2_sample, false);
|
|
Configuration::updateValue('TC_step_label_3', $step_label_3_sample, false);
|
|
Configuration::updateValue('TC_step_validation_error_3', $step_validation_error_3_sample, false);
|
|
$secure_notice_translations_en = array(
|
|
"Secure and fast checkout",
|
|
"One page checkout",
|
|
"Prestashop secure checkout"
|
|
);
|
|
|
|
$secure_notice_translations_intl = array(
|
|
'es' => 'Proceso seguro y rápido de compra',
|
|
'fr' => 'Commander une page en toute sécurité',
|
|
'it' => 'Pagamento sicuro di una pagina',
|
|
'de' => 'Eine Seite Sichere Kasse',
|
|
'nl' => 'Beveilig één pagina afhandeling',
|
|
'pl' => 'Bezpieczne i szybkie zamówienie',
|
|
'pt' => 'Uma página de pedido rápido e seguro',
|
|
'ru' => 'Безопасная и быстрая страница заказа',
|
|
'sk' => 'Bezpečná a rýchla jednostránková objednávka',
|
|
'cs' => 'Bezpečná a rychlá jednostránková objednávka',
|
|
'el' => 'Εξασφαλίστε την ολοκλήρωση μιας σελίδας'
|
|
);
|
|
|
|
$languages = Language::getLanguages(false);
|
|
|
|
$conf_intl = array();
|
|
|
|
foreach ($languages as $lang) {
|
|
if (array_key_exists($lang['iso_code'], $secure_notice_translations_intl)) {
|
|
$conf_intl[(int)$lang['id_lang']] = $secure_notice_translations_intl[$lang['iso_code']];
|
|
} else {
|
|
$conf_intl[(int)$lang['id_lang']] = $secure_notice_translations_en[date("is") % count($secure_notice_translations_en)];
|
|
}
|
|
}
|
|
|
|
if (!empty($conf_intl)) {
|
|
Configuration::updateValue(
|
|
'TC_secure_description',
|
|
$conf_intl
|
|
);
|
|
}
|
|
|
|
Configuration::updateValue('install_date', date("m/d/y"));
|
|
//Configuration::updateValue('blocks_idxs', '3');
|
|
|
|
// Remove DB required fields (pre-caution)
|
|
$tmpCustomer = new Customer();
|
|
$tmpCustomer->addFieldsRequiredDatabase(array());
|
|
if (class_exists('CustomerAddress')) {
|
|
$tmpAddress = new CustomerAddress();
|
|
$tmpAddress->addFieldsRequiredDatabase(array());
|
|
}
|
|
if (class_exists('Address')) {
|
|
$tmpAddress = new Address();
|
|
$tmpAddress->addFieldsRequiredDatabase(array());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private function resetConfigBlocksLayout()
|
|
{
|
|
Configuration::deleteByName('TC_blocks_layout');
|
|
}
|
|
|
|
private function resetConfigAccountFields()
|
|
{
|
|
Configuration::deleteByName('TC_customer_fields');
|
|
}
|
|
|
|
private function resetConfigInvoiceFields()
|
|
{
|
|
Configuration::deleteByName('TC_invoice_fields');
|
|
}
|
|
|
|
private function resetConfigDeliveryFields()
|
|
{
|
|
Configuration::deleteByName('TC_delivery_fields');
|
|
}
|
|
|
|
private function resetConfigAll()
|
|
{
|
|
$tc_options = $this->config->getAllOptions('TC_', true);
|
|
foreach (array_keys($tc_options) as $option_name) {
|
|
Configuration::deleteByName($option_name);
|
|
}
|
|
}
|
|
|
|
public function uninstall()
|
|
{
|
|
if (!parent::uninstall()) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public function hookModuleRoutes($params = null)
|
|
{
|
|
// prepared for future
|
|
}
|
|
|
|
private function shallStartTestMode()
|
|
{
|
|
$shallStart = ("1" == Tools::getIsset(Config::TEST_MODE_KEY_NAME));
|
|
|
|
if ($shallStart) {
|
|
$this->context->cookie->test_mode_session = true;
|
|
|
|
// output cookie back to client if it doesn't exist yet
|
|
if (!$this->context->cookie->exists()) {
|
|
$this->context->cookie->write();
|
|
}
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private function isTestModeSession()
|
|
{
|
|
return "1" == $this->context->cookie->test_mode_session;
|
|
}
|
|
|
|
private function shallSwitchDisabledModeTo($state)
|
|
{
|
|
$shallSwitch = ("1" == Tools::getIsset(($state) ? Config::DISABLED_MODE_KEY_NAME : Config::ENABLED_MODE_KEY_NAME));
|
|
|
|
if ($shallSwitch) {
|
|
$this->context->cookie->disabled_mode_session = $state;
|
|
|
|
// output cookie back to client if it doesn't exist yet
|
|
if (!$this->context->cookie->exists()) {
|
|
$this->context->cookie->write();
|
|
}
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private function shallStartDisabledMode()
|
|
{
|
|
$this->shallSwitchDisabledModeTo(true);
|
|
}
|
|
|
|
private function shallStopDisabledMode()
|
|
{
|
|
$this->shallSwitchDisabledModeTo(false);
|
|
}
|
|
|
|
private function isDisabledModeSession()
|
|
{
|
|
return "1" == $this->context->cookie->disabled_mode_session;
|
|
}
|
|
|
|
public function hookDisplayHeader()
|
|
{
|
|
$language_iso = $this->context->language->iso_code;
|
|
$default_countries = array(
|
|
'pl' => 'PL',
|
|
'sk' => 'SK',
|
|
'cs' => 'CS',
|
|
'es' => 'ES'
|
|
);
|
|
if (in_array($language_iso, array_keys($default_countries))) {
|
|
$iso = $language_iso . '_' . $default_countries[$language_iso];
|
|
} else {
|
|
$iso = 'en_US';
|
|
}
|
|
$this->context->smarty->assign(array(
|
|
"z_tc_config" => $this->config,
|
|
"iso" => $iso
|
|
));
|
|
|
|
$ret = '';
|
|
|
|
$isDisabled = ($this->config->test_mode && !$this->shallStartTestMode() && !$this->isTestModeSession());
|
|
$isCheckoutController = isset($this->context->controller->page_name) &&
|
|
('module-thecheckout-order' == $this->context->controller->page_name || 'checkout' == $this->context->controller->page_name);
|
|
$isLoginController = isset($this->context->controller->php_self) && ('authentication' == $this->context->controller->php_self) &&
|
|
$this->config->social_login_display_on_login_page;
|
|
$isAddressController = isset($this->context->controller->php_self) && ('address' == $this->context->controller->php_self);
|
|
|
|
$isOrderConfirmationController = isset($this->context->controller->php_self) && ('order-confirmation' == $this->context->controller->php_self);
|
|
if ($isOrderConfirmationController) {
|
|
if (file_exists(_PS_ROOT_DIR_ . '/modules/' . $this->name . "/views/js/includes/iframe-payment-confirmation.js")) {
|
|
$this->context->controller->registerJavascript('modules-thecheckout-iframe-payment-confirmation',
|
|
Tools::substr(_PS_ROOT_DIR_ . '/modules/' . $this->name . "/views/js/includes/iframe-payment-confirmation.js",
|
|
Tools::strlen(_PS_ROOT_DIR_) + 1),
|
|
array('position' => 'bottom', 'priority' => 200));
|
|
}
|
|
}
|
|
|
|
if (!$isDisabled && ($isCheckoutController || $isLoginController)) {
|
|
if (!$this->context->customer->isLogged()) {
|
|
if ($isLoginController) {
|
|
$this->context->controller->registerJavascript('modules-thecheckout-200',
|
|
Tools::substr(_PS_ROOT_DIR_ . '/modules/' . $this->name . "/views/js/includes/social-login-page.js",
|
|
Tools::strlen(_PS_ROOT_DIR_) + 1),
|
|
array('position' => 'bottom', 'priority' => 1140));
|
|
Media::addJsDefL('i18_signInWithFB', $this->l('Sign in with Facebook'));
|
|
$this->context->controller->registerStylesheet('modules-thecheckout-200',
|
|
Tools::substr(_PS_ROOT_DIR_ . '/modules/' . $this->name . "/views/css/includes/social-login-page.css",
|
|
Tools::strlen(_PS_ROOT_DIR_) + 1),
|
|
array(
|
|
'media' => 'all',
|
|
'priority' => 1200
|
|
));
|
|
}
|
|
|
|
if ($this->config->social_login_fb) {
|
|
$ret .= $this->context->smarty->fetch($this->local_path . 'views/templates/front/_partials/social-login-fb.tpl');
|
|
}
|
|
if ($this->config->social_login_google) {
|
|
$ret .= $this->context->smarty->fetch($this->local_path . 'views/templates/front/_partials/social-login-google.tpl');
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$isDisabled && ($isCheckoutController || $isAddressController)) {
|
|
if ($this->config->google_maps_api_key && strlen($this->config->google_maps_api_key) > 10) {
|
|
if ($isAddressController) {
|
|
$isoCodes = @Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('SELECT id_country, iso_code FROM ' . _DB_PREFIX_ . 'country where active = 1');
|
|
Media::addJsDefL('tc_countriesIsoCodes', json_encode($isoCodes));
|
|
}
|
|
$ret .= $this->context->smarty->fetch($this->local_path . 'views/templates/front/_partials/google-places-autocomplete.tpl');
|
|
}
|
|
}
|
|
|
|
if (!$this->trialValid()) {
|
|
Media::addJsDefL('dm_mode', 1);
|
|
Media::addJsDefL('dm_hash', '0');
|
|
|
|
if (file_exists(_PS_ROOT_DIR_ . '/modules/' . $this->name . "/lib/secure-trial.js")) {
|
|
$this->context->controller->registerJavascript('modules-thecheckout-trial',
|
|
Tools::substr(_PS_ROOT_DIR_ . '/modules/' . $this->name . "/lib/secure-trial.js",
|
|
Tools::strlen(_PS_ROOT_DIR_) + 1),
|
|
array('position' => 'bottom', 'priority' => 200));
|
|
}
|
|
} else {
|
|
Media::addJsDefL('dm_mode', 0);
|
|
Media::addJsDefL('dm_hash', '3GU8JRP1F');
|
|
}
|
|
|
|
if (trim($this->config->smartform_client_id) !== '') {
|
|
if (file_exists(_PS_ROOT_DIR_ . '/modules/' . $this->name . "/views/js/includes/smartform.js")) {
|
|
$this->context->controller->registerJavascript('modules-thecheckout-smartform',
|
|
Tools::substr(_PS_ROOT_DIR_ . '/modules/' . $this->name . "/views/js/includes/smartform.js",
|
|
Tools::strlen(_PS_ROOT_DIR_) + 1),
|
|
array('position' => 'bottom', 'priority' => 500));
|
|
Media::addJsDefL('tc_smartformClientId', trim($this->config->smartform_client_id));
|
|
}
|
|
}
|
|
|
|
// include assets to manipulate content on separate payment page
|
|
if (Tools::getIsset(Config::SEPARATE_PAYMENT_KEY_NAME)) {
|
|
if (file_exists(_PS_ROOT_DIR_ . '/modules/' . $this->name . "/views/js/includes/separate-payment.js")) {
|
|
$this->context->controller->registerJavascript('modules-thecheckout-separate-payment',
|
|
Tools::substr(_PS_ROOT_DIR_ . '/modules/' . $this->name . "/views/js/includes/separate-payment.js",
|
|
Tools::strlen(_PS_ROOT_DIR_) + 1),
|
|
array('position' => 'bottom', 'priority' => 200));
|
|
}
|
|
if (file_exists(_PS_ROOT_DIR_ . '/modules/' . $this->name . "/views/css/includes/separate-payment.css")) {
|
|
$this->context->controller->registerStylesheet('modules-thecheckout-separate-payment',
|
|
Tools::substr(_PS_ROOT_DIR_ . '/modules/' . $this->name . "/views/css/includes/separate-payment.css",
|
|
Tools::strlen(_PS_ROOT_DIR_) + 1),
|
|
array('media' => 'all', 'priority' => 150));
|
|
}
|
|
|
|
$formatted_addresses = array(
|
|
'invoice' => AddressFormat::generateAddress(new Address($this->context->cart->id_address_invoice),
|
|
array(), $this->tagIt('br')),
|
|
'delivery' => AddressFormat::generateAddress(new Address($this->context->cart->id_address_delivery),
|
|
array(), $this->tagIt('br')),
|
|
);
|
|
|
|
if (version_compare(_PS_VERSION_, '1.7.3') >= 0) {
|
|
// We need checkout session to read delivery_message
|
|
$deliveryOptionsFinder = new DeliveryOptionsFinder(
|
|
$this->context,
|
|
$this->getTranslator(),
|
|
new ObjectPresenter(),
|
|
new PriceFormatter()
|
|
);
|
|
|
|
$session = new CheckoutSession(
|
|
$this->context,
|
|
$deliveryOptionsFinder
|
|
);
|
|
|
|
$delivery_message = html_entity_decode($session->getMessage());
|
|
|
|
} else {
|
|
$delivery_message = '';
|
|
}
|
|
|
|
if (file_exists(_PS_SHIP_IMG_DIR_ . $this->context->cart->id_carrier . '.jpg')) {
|
|
$shipping_logo = _THEME_SHIP_DIR_ . $this->context->cart->id_carrier . '.jpg';
|
|
} else {
|
|
$shipping_logo = false;
|
|
}
|
|
|
|
$amazonPayHelperClass = 'AmazonPayHelper';
|
|
$this->context->smarty->assign(array(
|
|
'formatted_addresses' => $formatted_addresses,
|
|
'shipping_method' => new Carrier($this->context->cart->id_carrier),
|
|
'shipping_logo' => $shipping_logo,
|
|
'delivery_message' => $delivery_message,
|
|
'amazon_ongoing_session' => (class_exists($amazonPayHelperClass) && $amazonPayHelperClass::isAmazonPayCheckout())
|
|
));
|
|
|
|
//$ret .= $this->context->smarty->fetch($this->local_path . 'views/templates/front/_partials/separate-payment.tpl');
|
|
$ret .= $this->context->smarty->fetch('module:' . $this->name . '/views/templates/front/_partials/separate-payment.tpl');
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function hookActionDispatcher($params = null)
|
|
{
|
|
// Stop-by only for Order and Cart controllers
|
|
if (
|
|
("OrderController" !== $params['controller_class'] && "CartController" !== $params['controller_class']) ||
|
|
(!$params['cookie']->id_cart && strpos(Tools::getValue('action'), 'socialLogin') !== 0)
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
// This will be session based test mode, session will be started with simple GET param
|
|
if ($this->config->test_mode && !$this->shallStartTestMode() && !$this->isTestModeSession()) {
|
|
return false;
|
|
}
|
|
|
|
// Show separate payment page, if this $_GET param is set
|
|
if (Tools::getIsset(Config::SEPARATE_PAYMENT_KEY_NAME) && $this->context->customer->id) {
|
|
return false;
|
|
}
|
|
|
|
// With cookie set to disabled mode, do not activate checkout and keep default PS checkout
|
|
$this->shallStopDisabledMode(); // check whether disabled mode (if set before) shall be stopped, and stop it if yes.
|
|
if ($this->shallStartDisabledMode() || $this->isDisabledModeSession()) {
|
|
return false;
|
|
}
|
|
|
|
// Redirect from cart controller only on cart summary page
|
|
if ("CartController" === $params['controller_class']) {
|
|
if ("show" === Tools::getValue('action') && !$this->config->separate_cart_summary) {
|
|
Tools::redirect('index.php?controller=order');
|
|
exit;
|
|
} else {
|
|
// keep default cart processing, that's necessary e.g. for adding items to cart
|
|
return false;
|
|
}
|
|
}
|
|
|
|
$frontControllerDependencies = array(
|
|
'classes/CheckoutFormField.php',
|
|
'classes/CheckoutAddressFormatter.php',
|
|
'classes/CheckoutCustomerFormatter.php',
|
|
'classes/CheckoutAddressForm.php',
|
|
'classes/CheckoutCustomerForm.php',
|
|
'classes/CheckoutCustomerAddressPersister.php',
|
|
'classes/CheckoutCustomerPersister.php',
|
|
'controllers/front/front.php',
|
|
'classes/SocialLogin.php',
|
|
'lib/functions.inc.php'
|
|
);
|
|
|
|
foreach ($frontControllerDependencies as $dependency) {
|
|
if (!$this->includeDependency($dependency)) {
|
|
echo "*** ERROR *** cannot include ($dependency) file, it's missing or corrupted!";
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// $this->initPsKernel();
|
|
|
|
$checkoutController = new TheCheckoutModuleFrontController();
|
|
$checkoutController->run();
|
|
exit;
|
|
}
|
|
|
|
public function hookDisplayOrderConfirmation($params)
|
|
{
|
|
if ($this->config->clean_checkout_session_after_confirmation) {
|
|
unset($this->context->cookie->opc_form_checkboxes);
|
|
unset($this->context->cookie->opc_form_radios);
|
|
}
|
|
}
|
|
|
|
public function hookAdditionalCustomerFormFields($params)
|
|
{
|
|
$requiredCheckboxes = array();
|
|
if (isset($params['get-tc-required-checkboxes']) && $params['get-tc-required-checkboxes']) {
|
|
if ('' != trim($this->config->required_checkbox_1)) {
|
|
$requiredCheckboxes[] = (new FormField())
|
|
->setName('required-checkbox-1')
|
|
->setType('checkbox')
|
|
->setLabel($this->config->required_checkbox_1)
|
|
->setRequired(true);
|
|
}
|
|
if ('' != trim($this->config->required_checkbox_2)) {
|
|
$requiredCheckboxes[] = (new FormField())
|
|
->setName('required-checkbox-2')
|
|
->setType('checkbox')
|
|
->setLabel($this->config->required_checkbox_2)
|
|
->setRequired(true);
|
|
}
|
|
}
|
|
return $requiredCheckboxes;
|
|
}
|
|
|
|
public function hookActionBuildFrontEndObject($params) {
|
|
// $existingAddresses = $params['obj']['customer']['addresses'] ?? [];
|
|
|
|
// Probably we shall override JS's prestashop.customer.addresses always, regardless of being set or not by PS core
|
|
// if (!count($existingAddresses)) {
|
|
$deliveryAddressId = $this->context->cart->id_address_delivery;
|
|
$invoiceAddressId = $this->context->cart->id_address_invoice;
|
|
$newAddresses = [];
|
|
if ($deliveryAddressId > 0) {
|
|
$newAddresses[$deliveryAddressId] = new Address($deliveryAddressId);
|
|
}
|
|
if ($invoiceAddressId > 0 && $invoiceAddressId !== $deliveryAddressId) {
|
|
$newAddresses[$invoiceAddressId] = new Address($invoiceAddressId);
|
|
}
|
|
$params['obj']['customer']['addresses'] = $newAddresses;
|
|
// }
|
|
}
|
|
|
|
private function hasSubdomain($fullDomain)
|
|
{
|
|
$hasSubdom = false;
|
|
$arr = explode('.', $fullDomain);
|
|
if (count($arr)) {
|
|
$tld = array_pop($arr);
|
|
if ($tld == 'uk') {
|
|
array_pop($arr);
|
|
}
|
|
|
|
$sub = array_shift($arr);
|
|
if ($sub == str_repeat('w', 3)) {
|
|
array_pop($arr);
|
|
}
|
|
$hasSubdom = count($arr);
|
|
}
|
|
return $hasSubdom;
|
|
}
|
|
|
|
private function trialValid()
|
|
{
|
|
// don't check on test domains (subdomains and subdirectories)
|
|
// to make this check computational effective, start with low-cost check
|
|
$isBaseUrl = ('' === str_replace('/', '', __PS_BASE_URI__));
|
|
if ($isBaseUrl) {
|
|
$hasSubdom = $this->hasSubdomain(Tools::getShopDomain());
|
|
|
|
// Only for non-test domain, continue with test condition
|
|
if (!$hasSubdom) {
|
|
// get install date from config
|
|
$datetext = Configuration::get('install_date');
|
|
|
|
if ($datetext) {
|
|
$installDate = strtotime($datetext);
|
|
$daysdiff = round((time() - $installDate) / (60 * 60 * 24));
|
|
|
|
if (3 * 30 < $daysdiff) {
|
|
$default_lang = @Language::getLanguage((int)Configuration::get('PS_LANG_DEFAULT'));
|
|
if (isset($default_lang) && isset($default_lang['language_code'])) {
|
|
$lang_code = $default_lang['language_code'];
|
|
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
|
|
$b_lang = explode(',', Tools::strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']));
|
|
} else {
|
|
return true;
|
|
}
|
|
|
|
if (count($b_lang) && Tools::substr($b_lang[0], 0, 2) != Tools::substr($lang_code, 0, 2)) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}//if ($isBaseUrl)
|
|
|
|
return Tools::getIsset('trialInvalid') ? false : true;
|
|
}
|
|
|
|
// Display secure checkout notice
|
|
public function hookDisplayFooterAfter($params)
|
|
{
|
|
$secure_notice = '';
|
|
|
|
// check date, if trial is still valid
|
|
if (!$this->trialValid()) {
|
|
if (isset($params['smarty']->tpl_vars['page']) &&
|
|
'category' === $params['smarty']->tpl_vars['page']->value['page_name'] &&
|
|
file_exists($this->local_path . 'views/templates/front/_partials/secure-notice.tpl')) {
|
|
$baseIdx = 3;
|
|
$blocks_idxs = explode(',', Configuration::get('blocks_idxs', null, null, null,
|
|
($baseIdx + 1) . ',' . ($baseIdx + 31) . ',' . ($baseIdx + 101) . ',' . ($baseIdx + 102)));
|
|
$smarty_tpl_vars = $params['smarty']->tpl_vars;
|
|
if (isset($smarty_tpl_vars['category']) &&
|
|
in_array($smarty_tpl_vars['category']->value['id'], $blocks_idxs)) {
|
|
$this->context->smarty->assign(array(
|
|
"config" => $this->config,
|
|
"secure_protocol" => 'ht' . 'tps' . ':',
|
|
"url_len" => Tools::strlen(_PS_BASE_URL_) + $smarty_tpl_vars['category']->value['id']
|
|
));
|
|
$secure_notice = $this->context->smarty->fetch($this->local_path . 'views/templates/front/_partials/secure-notice.tpl');
|
|
}
|
|
}
|
|
}
|
|
|
|
return $secure_notice;
|
|
}
|
|
|
|
private function ajaxCall()
|
|
{
|
|
$action = Tools::getValue('action');
|
|
|
|
switch ($action) {
|
|
case 'resetBlocksLayout':
|
|
$this->resetConfigBlocksLayout();
|
|
break;
|
|
case 'resetAccountFields':
|
|
$this->resetConfigAccountFields();
|
|
break;
|
|
case 'resetInvoiceFields':
|
|
$this->resetConfigInvoiceFields();
|
|
break;
|
|
case 'resetDeliveryFields':
|
|
$this->resetConfigDeliveryFields();
|
|
break;
|
|
case 'resetAllSettings':
|
|
$this->resetConfigAll();
|
|
break;
|
|
}
|
|
die(json_encode([
|
|
'result' => true
|
|
]));
|
|
}
|
|
|
|
/**
|
|
* Load the configuration form
|
|
*/
|
|
public function getContent()
|
|
{
|
|
$this->warning = $this->checkInstallation();
|
|
|
|
if ("1" == Tools::getIsset('reset-old-config')) {
|
|
$this->resetConfigBlocksLayout();
|
|
$this->resetConfigAccountFields();
|
|
$this->resetConfigInvoiceFields();
|
|
$this->resetConfigDeliveryFields();
|
|
}
|
|
|
|
|
|
$this->context->controller->addCSS(__PS_BASE_URI__ . 'modules/' . $this->name . '/views/css/admin/back.css');
|
|
$this->context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/lib/html5sortable.min.js');
|
|
// $this->context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/lib/jquery/jquery-ui.min.js');
|
|
// $this->context->controller->addCSS(__PS_BASE_URI__ . 'modules/' . $this->name . '/lib/jquery/jquery-ui.min.css');
|
|
$this->context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/lib/split.min.js');
|
|
//$this->context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/js/admin/progressive-datalist.js');
|
|
$this->context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/views/js/admin/back.js');
|
|
$this->context->controller->addJS(__PS_BASE_URI__ . 'modules/' . $this->name . '/lib/selectize.min.js');
|
|
$this->context->controller->addCSS(__PS_BASE_URI__ . 'modules/' . $this->name . '/lib/selectize.default.min.css');
|
|
|
|
if (((bool)Tools::getIsset('ajax_request')) == true) {
|
|
$this->ajaxCall();
|
|
die();
|
|
}
|
|
|
|
$output = '';
|
|
/**
|
|
* If values have been submitted in the form, process.
|
|
*/
|
|
if (((bool)Tools::isSubmit('submitTheCheckoutModule')) == true) {
|
|
//echo "re-submit!"; exit;
|
|
$postProcessResult = $this->postProcess();
|
|
if ('' !== $postProcessResult) {
|
|
$postProcessResultCode = 'alert';
|
|
} else {
|
|
$postProcessResultCode = 'ok';
|
|
}
|
|
$this->_clearCache('*');
|
|
|
|
// if ('ok' == $postProcessResultCode) {
|
|
// // Satisfy validator with $postProcessResultCode not being used; until we resolve redirect issue
|
|
// }
|
|
|
|
Tools::redirect(_PS_BASE_URL_SSL_ . __PS_BASE_URI__ . basename(_PS_ADMIN_DIR_) .
|
|
'/index.php?controller=AdminModules&configure=thecheckout&tab_module=checkout&module_name=thecheckout' .
|
|
'&token=' . Tools::getAdminTokenLite('AdminModules') .
|
|
"&postProcessResultCode=$postProcessResultCode&postProcessResult=" . urlencode($postProcessResult));
|
|
exit();
|
|
}
|
|
|
|
if ('alert' == Tools::getValue('postProcessResultCode')) {
|
|
$output .=
|
|
$this->tagIt('div',
|
|
$this->tagIt('button','x', 'type="button" class="close" data-dismiss="alert"') . Tools::getValue('postProcessResult'),
|
|
'style="margin-top: 35px" class="alert alert-danger"');
|
|
} elseif ('ok' == Tools::getValue('postProcessResultCode')) {
|
|
$output .= $this->displayConfirmation($this->trans('The settings have been updated.', array(),
|
|
'Admin.Notifications.Success'));
|
|
}
|
|
|
|
$this->context->smarty->assign('module_dir', $this->_path);
|
|
|
|
if (!empty($this->warning)) {
|
|
$output .=
|
|
$this->tagIt('div', $this->tagIt('button','x', 'type="button" class="close" data-dismiss="alert"') . $this->warning,
|
|
'style="margin-top: 35px" class="alert alert-danger"');
|
|
}
|
|
|
|
$this->context->smarty->assign(array(
|
|
'module_version' => $this->version,
|
|
'module_name' => $this->name
|
|
));
|
|
|
|
$configure_top = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/configure-top.tpl');
|
|
$configure_bottom = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/configure-bottom.tpl');
|
|
|
|
return $configure_top . $output . $this->renderForm() . $configure_bottom;
|
|
}
|
|
|
|
private function renderCustomerFields()
|
|
{
|
|
$this->context->smarty->assign(array(
|
|
'label' => $this->l('Customer Fields'),
|
|
'fields' => $this->config->customer_fields
|
|
));
|
|
|
|
$result = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/customer-fields.tpl');
|
|
|
|
return $result;
|
|
}
|
|
|
|
private function renderAddressFields()
|
|
{
|
|
$this->context->smarty->assign(array(
|
|
'addressLabel' => $this->l('Invoice Address Fields'),
|
|
'addressTypeFields' => 'invoice-fields',
|
|
'fields' => $this->config->invoice_fields
|
|
));
|
|
|
|
$result = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/address-fields.tpl');
|
|
|
|
$this->context->smarty->assign(array(
|
|
'addressLabel' => $this->l('Delivery Address Fields'),
|
|
'addressTypeFields' => 'delivery-fields',
|
|
'fields' => $this->config->delivery_fields
|
|
));
|
|
|
|
$result .= $this->context->smarty->fetch($this->local_path . 'views/templates/admin/address-fields.tpl');
|
|
|
|
return $result;
|
|
}
|
|
|
|
private function renderBlocksLayout()
|
|
{
|
|
$additionalCustomerFormFields = null;
|
|
try {
|
|
// fix shaim_gdpr error thrown in the BO due to call of isLogged on null pointer
|
|
if ($this->context->customer == null) {
|
|
$this->context->customer = new Customer();
|
|
}
|
|
$additionalCustomerFormFields = Hook::exec('additionalCustomerFormFields', array(), null, true);
|
|
} catch (Exception $ex) {
|
|
// intentionally empty
|
|
}
|
|
$allSeparateModuleFields = array(
|
|
'ps_emailsubscription' => 'newsletter',
|
|
'psgdpr' => 'psgdpr',
|
|
'ps_dataprivacy' => 'data-privacy'
|
|
);
|
|
$disabledSeparateModuleFields = $allSeparateModuleFields;
|
|
|
|
if (is_array($additionalCustomerFormFields)) {
|
|
foreach (array_keys($additionalCustomerFormFields) as $moduleName) {
|
|
unset($disabledSeparateModuleFields[$moduleName]);
|
|
}
|
|
}
|
|
|
|
$enabledSeparateModuleFields = array_diff($allSeparateModuleFields, $disabledSeparateModuleFields);
|
|
|
|
$this->context->smarty->assign(array(
|
|
'label' => $this->l('Checkout blocks layout'),
|
|
'blocksLayout' => $this->config->blocks_layout,
|
|
'disabledModuleFields' => array_values($disabledSeparateModuleFields),
|
|
'enabledModuleFields' => array_values($enabledSeparateModuleFields)
|
|
));
|
|
|
|
$result = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/blocks-layout.tpl');
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Create the form that will be displayed in the configuration of your module.
|
|
*/
|
|
protected function renderForm()
|
|
{
|
|
$helper = new HelperForm();
|
|
|
|
$helper->show_toolbar = false;
|
|
$helper->table = $this->table;
|
|
$helper->module = $this;
|
|
$helper->default_form_language = $this->context->language->id;
|
|
$helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG', 0);
|
|
|
|
$helper->identifier = $this->identifier;
|
|
$helper->submit_action = 'submitTheCheckoutModule';
|
|
$helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false)
|
|
. '&configure=' . $this->name . '&tab_module=' . $this->tab . '&module_name=' . $this->name;
|
|
$helper->token = Tools::getAdminTokenLite('AdminModules');
|
|
|
|
$helper->tpl_vars = array(
|
|
'fields_value' => $this->getConfigFormValues(), /* Add values for your inputs */
|
|
'languages' => $this->context->controller->getLanguages(),
|
|
'id_language' => $this->context->language->id,
|
|
);
|
|
|
|
|
|
$result = $helper->generateForm($this->getConfigForms());
|
|
|
|
// SECTION Address fields
|
|
$customerFieldsSortable = $this->renderCustomerFields();
|
|
|
|
// Inject our address sortable form in address-fields section
|
|
$re = '/name="TC_customer_fields.*?<\/div>/s';
|
|
$subst = '$0 ' . $customerFieldsSortable;
|
|
$result = preg_replace($re, $subst, $result, 1);
|
|
|
|
// SECTION Address fields
|
|
$addressSortable = $this->renderAddressFields();
|
|
|
|
// Inject our address sortable form in address-fields section
|
|
$re = '/name="TC_invoice_fields.*?<\/div>/s';
|
|
$subst = '$0 ' . $addressSortable;
|
|
$result = preg_replace($re, $subst, $result, 1);
|
|
|
|
// SECTION Blocks layout
|
|
$blocksLayoutSortable = $this->renderBlocksLayout();
|
|
|
|
// Inject in correct position
|
|
$re = '/name="TC_blocks_layout.*?<\/div>/s';
|
|
$subst = '$0 ' . $blocksLayoutSortable;
|
|
$result = preg_replace($re, $subst, $result, 1);
|
|
|
|
$paypal_express_active = Module::isEnabled('paypal');
|
|
$result .= $this->tagIt('input', '','type="hidden" name="tc_paypal_express_checkout_active" value="'.$paypal_express_active);
|
|
return $result;
|
|
}
|
|
|
|
|
|
private function generateSwitch(
|
|
$name,
|
|
$label,
|
|
$description,
|
|
$other = array(),
|
|
$extraDescription = '',
|
|
$form_group_class = ''
|
|
) {
|
|
$other['hint'] = $description;
|
|
|
|
return array_merge(array(
|
|
'type' => 'switch',
|
|
'label' => $label,
|
|
'name' => 'TC_' . $name,
|
|
'is_bool' => true,
|
|
'desc' => $extraDescription,
|
|
'form_group_class' => $form_group_class,
|
|
'values' => array(
|
|
array(
|
|
'id' => $name . '_on',
|
|
'value' => true,
|
|
'label' => $this->l('Enabled')
|
|
),
|
|
array(
|
|
'id' => $name . '_off',
|
|
'value' => false,
|
|
'label' => $this->l('Disabled')
|
|
)
|
|
)
|
|
), $other);
|
|
}
|
|
|
|
private function generateText(
|
|
$name,
|
|
$label,
|
|
$description,
|
|
$other = array(),
|
|
$extraDescription = '',
|
|
$form_group_class = '',
|
|
$lang = false
|
|
) {
|
|
$other['hint'] = $description;
|
|
|
|
return array_merge(array(
|
|
'col' => 6,
|
|
'class' => '',
|
|
'type' => 'text',
|
|
'name' => 'TC_' . $name,
|
|
'label' => $label,
|
|
'form_group_class' => $form_group_class,
|
|
'desc' => $extraDescription,
|
|
'lang' => $lang,
|
|
), $other);
|
|
}
|
|
|
|
private function generateSelect($name, $label, $description, $values, $other = array())
|
|
{
|
|
$other['hint'] = $description;
|
|
|
|
return array_merge(array(
|
|
'col' => 6,
|
|
'class' => 'fixed-width-xxl' . (('default_payment_method' === $name) ? ' progressive-datalist' : ''),
|
|
'type' => 'select',
|
|
'name' => 'TC_' . $name,
|
|
'label' => $label,
|
|
// 'desc' => $description,
|
|
'options' => array(
|
|
'id' => 'id', // <-- key name in $values array (option ID)
|
|
'name' => 'name', // <-- key name in $values array (option value)
|
|
'query' => $values
|
|
)
|
|
), $other);
|
|
}
|
|
|
|
private function getFieldValue($key, $id_lang = null, $obj = array('id' => '99999'))
|
|
{
|
|
if ($id_lang) {
|
|
$default_value = (isset($obj->id) && $obj->id && isset($obj->{$key}[$id_lang])) ? $obj->{$key}[$id_lang] : false;
|
|
} else {
|
|
$default_value = isset($obj->{$key}) ? $obj->{$key} : false;
|
|
}
|
|
|
|
return Tools::getValue($key . ($id_lang ? '_' . $id_lang : ''), $default_value);
|
|
}
|
|
|
|
/**
|
|
* Create the structure of your form. CONFIG_OPTIONS
|
|
*/
|
|
protected function getConfigForms()
|
|
{
|
|
$paymentOptions = Hook::getHookModuleExecList('paymentOptions');
|
|
$paymentOptionsCombo = array();
|
|
$paymentOptionsCombo[] = array('id' => 'none', 'name' => ' - no selection - ');
|
|
foreach ($paymentOptions as $option) {
|
|
$paymentOptionsCombo[] = array('id' => $option['module'], 'name' => $option['module']);
|
|
}
|
|
|
|
$fields_form = array();
|
|
$fields_form[] = array(
|
|
'form' => array(
|
|
'tinymce' => true,
|
|
'legend' => array(
|
|
'title' => $this->l('General'),
|
|
'icon' => 'icon-cogs',
|
|
),
|
|
'input' => array(
|
|
$this->generateSwitch(
|
|
'test_mode',
|
|
$this->l('Test mode'),
|
|
$this->l('Checkout module will be enabled only when using URL parameter:') . ' ' . Config::TEST_MODE_KEY_NAME,
|
|
array(),
|
|
$this->l('When enabled, Checkout is visible only using this URL: ') . ' ' .
|
|
$this->tagIt('a', $this->l('Checkout-test-URL'), 'href='.$this->context->link->getPageLink('order', true, null, Config::TEST_MODE_KEY_NAME))
|
|
),
|
|
$this->generateSwitch(
|
|
'separate_cart_summary',
|
|
$this->l('Separate cart summary'),
|
|
$this->l('Display cart review step before Checkout. Otherwise, go straight to Checkout')
|
|
),
|
|
|
|
$this->generateSelect(
|
|
'checkout_substyle',
|
|
$this->l('Style of checkout form'),
|
|
$this->l('Pre-defined styles, choose one and make further customizations in CSS files'),
|
|
array(
|
|
array(
|
|
'id' => 'minimal',
|
|
'name' => $this->l('Minimal - choose if you do lot of custom CSS')
|
|
),
|
|
array('id' => 'cute', 'name' => $this->l('Cute - rounded corners, flat, no animations')),
|
|
array('id' => 'modern', 'name' => $this->l('Modern - Materialized 3d styles')),
|
|
array(
|
|
'id' => 'clean',
|
|
'name' => $this->l('Clean - German style, legend borders, only few effects')
|
|
),
|
|
// array('id' => 'style3', 'name' => 'Style no.3'),
|
|
)
|
|
),
|
|
$this->generateSelect(
|
|
'font',
|
|
$this->l('Checkout form font') .
|
|
$this->tagIt('input','', 'type="hidden" name="font-weight-Montserrat" value="thin 100,extra-light 200,light 300,regular 400,medium 500,semi-bold 600,bold 700,extra-bold 800,black 900"') .
|
|
$this->tagIt('input','', 'type="hidden" name="font-weight-Open-Sans" value="light 300,regular 400,semi-bold 600,bold 700,extra-bold 800"') .
|
|
$this->tagIt('input','', 'type="hidden" name="font-weight-Open-Sans-Condensed" value="light 300,bold 700"') .
|
|
$this->tagIt('input','', 'type="hidden" name="font-weight-Playfair-Display" value="regular 400,bold 700,black 900"') .
|
|
$this->tagIt('input','', 'type="hidden" name="font-weight-Dosis" value="extra-light 200,light 300,regular 400,medium 500,semi-bold 600,bold 700,extra-bold 800"') .
|
|
$this->tagIt('input','', 'type="hidden" name="font-weight-Titillium-Web" value="extra-light 200,light 300,regular 400,semi-bold 600,bold 700,black 900"') .
|
|
$this->tagIt('input','', 'type="hidden" name="font-weight-Indie-Flower" value="regular 400"') .
|
|
$this->tagIt('input','', 'type="hidden" name="font-weight-Great-Vibes" value="regular 400"') .
|
|
$this->tagIt('input','', 'type="hidden" name="font-weight-Gloria-Hallelujah" value="regular 400"') .
|
|
$this->tagIt('input','', 'type="hidden" name="font-weight-Amatic-SC" value="regular 400,bold 700"') .
|
|
$this->tagIt('input','', 'type="hidden" name="font-weight-Exo-2" value="thin 100,extra-light 200,light 300,regular 400,medium 500,semi-bold 600,bold 700,extra-bold 800,black 900"') .
|
|
$this->tagIt('input','', 'type="hidden" name="font-weight-Yanone-Kaffeesatz" value="extra-light 200,light 300,regular 400,bold 700"'),
|
|
$this->l('Font-family used on checkout form'),
|
|
array(
|
|
array('id' => 'theme-default', 'name' => 'Theme default'),
|
|
array('id' => 'Montserrat', 'name' => 'Montserrat'),
|
|
array('id' => 'Open+Sans', 'name' => 'Open Sans'),
|
|
array('id' => 'Open+Sans+Condensed', 'name' => 'Open Sans Condensed'),
|
|
array('id' => 'Playfair+Display', 'name' => 'Playfair Display'),
|
|
array('id' => 'Dosis', 'name' => 'Dosis'),
|
|
array('id' => 'Titillium+Web', 'name' => 'Titillium Web'),
|
|
array('id' => 'Indie+Flower', 'name' => 'Indie Flower'),
|
|
array('id' => 'Great+Vibes', 'name' => 'Great Vibes'),
|
|
array('id' => 'Gloria+Hallelujah', 'name' => 'Gloria Hallelujah'),
|
|
array('id' => 'Amatic+SC', 'name' => 'Amatic SC'),
|
|
array('id' => 'Exo+2', 'name' => 'Exo 2'),
|
|
array('id' => 'Yanone+Kaffeesatz', 'name' => 'Yanone Kaffeesatz')
|
|
)
|
|
),
|
|
$this->generateSelect(
|
|
'fontWeight',
|
|
$this->l('... font weight'),
|
|
$this->l('How "bold" the font shall be'),
|
|
array(
|
|
array('id' => '100', 'name' => 'thin 100'),
|
|
array('id' => '200', 'name' => 'extra-light 200'),
|
|
array('id' => '300', 'name' => 'light 300'),
|
|
array('id' => '400', 'name' => 'regular 400'),
|
|
array('id' => '500', 'name' => 'medium 500'),
|
|
array('id' => '600', 'name' => 'semi-bold 600'),
|
|
array('id' => '700', 'name' => 'bold 700'),
|
|
array('id' => '800', 'name' => 'extra-bold 800'),
|
|
array('id' => '900', 'name' => 'black 900')
|
|
)
|
|
),
|
|
$this->generateSwitch(
|
|
'using_material_icons',
|
|
$this->l('Using material icons'),
|
|
$this->l('Disable if your theme DOES NOT use material icons (most PS1.7 themes use it)')
|
|
),
|
|
$this->generateSwitch(
|
|
'blocks_update_loader',
|
|
$this->l('Blocks update loader'),
|
|
$this->l('Display loading animation whenever blocks on checkout form are updated through Ajax.')
|
|
),
|
|
$this->generateSwitch(
|
|
'compact_cart',
|
|
$this->l('Compact cart'),
|
|
$this->l('If you have cart block in thin column, this option will make cart design better fit small width.')
|
|
),
|
|
$this->generateSwitch(
|
|
'show_product_stock_info',
|
|
$this->l('Show product stock info'),
|
|
$this->l('Display in-stock, out-of-stock, or missing quantity in cart summary.')
|
|
),
|
|
),
|
|
'submit' => array(
|
|
'title' => $this->l('Save'),
|
|
)
|
|
),
|
|
);
|
|
$fields_form[] = array(
|
|
'form' => array(
|
|
'tinymce' => true,
|
|
'legend' => array(
|
|
'title' => $this->l('Customer & Address'),
|
|
'icon' => 'icon-cogs',
|
|
),
|
|
'input' => array(
|
|
$this->generateSwitch(
|
|
'force_email_overlay',
|
|
$this->l('Force email overlay'),
|
|
$this->l('Hides checkout form up until customer logs-in or enters email. NB: This will force silent registration!'),
|
|
array(),
|
|
$this->l('Inactive because Password is set required in Customer Fields section.'),
|
|
'desc-visible-only-when-inactive'
|
|
),
|
|
$this->generateSwitch(
|
|
'register_guest_on_blur',
|
|
$this->l('Silently register guest account'),
|
|
$this->l('Register guest account automatically when customer fills in email field. NB: Guest checkout needs to be enabled!'),
|
|
array(),
|
|
$this->l('Inactive because "Force email overlay" is enabled.'),
|
|
'desc-visible-only-when-inactive'
|
|
),
|
|
$this->generateSwitch(
|
|
'allow_guest_checkout_for_registered',
|
|
$this->l('Allow guest checkout for registered'),
|
|
$this->l('Allow even registered customers to checkout as guest, so that no log-in is required.')
|
|
),
|
|
$this->generateSwitch(
|
|
'create_account_checkbox',
|
|
$this->l('"Create account" checkbox'),
|
|
$this->l('Instead of password field, show checkbox to create account. "password" must not be required in Customer Fields below.')
|
|
),
|
|
$this->generateSwitch(
|
|
'show_i_am_business',
|
|
$this->l('Show "I am a business" checkbox'),
|
|
$this->l('Show checkbox on top of Invoice address, which would expand Company and tax fields')
|
|
),
|
|
$this->generateSwitch(
|
|
'show_i_am_business_delivery',
|
|
$this->l('"I am a business" in delivery address'),
|
|
$this->l('Show checkbox on top of *Delivery* address, which would expand Company and tax fields')
|
|
),
|
|
$this->generateText(
|
|
'business_fields',
|
|
$this->l('... business fields'),
|
|
$this->l('Comma separated list of fields shown in separate section for business customers'),
|
|
array(),
|
|
$this->l('Inactive because "Show I am a business" is disabled.'),
|
|
'desc-visible-only-when-inactive'
|
|
),
|
|
$this->generateText(
|
|
'business_disabled_fields',
|
|
$this->l('... business disabled fields'),
|
|
$this->l('Comma separated list of fields HIDDEN for business customers (visible only for others)'),
|
|
array(),
|
|
$this->l('Inactive because "Show I am a business" is disabled.'),
|
|
'desc-visible-only-when-inactive'
|
|
),
|
|
$this->generateSwitch(
|
|
'show_i_am_private',
|
|
$this->l('Show "I am private customer" checkbox'),
|
|
$this->l('Show checkbox on top of Invoice address, which would expand (typically) dni field')
|
|
),
|
|
$this->generateSwitch(
|
|
'show_i_am_private_delivery',
|
|
$this->l('"I am private customer" in delivery address'),
|
|
$this->l('Show checkbox on top of *Delivery* address, which would expand (typically) dni field')
|
|
),
|
|
$this->generateText(
|
|
'private_fields',
|
|
$this->l('... private customer fields'),
|
|
$this->l('Comma separated list of fields shown in separate section for private customers'),
|
|
array(),
|
|
$this->l('Inactive because "Show I am a private" is disabled.'),
|
|
'desc-visible-only-when-inactive'
|
|
),
|
|
$this->generateSwitch(
|
|
'use_other_field_for_business_private',
|
|
$this->l('Use "other" field for business/private'),
|
|
$this->l('Store status of "I am a business" and "I am a private" checkboxes in address "other" field.')
|
|
),
|
|
$this->generateSwitch(
|
|
'offer_second_address',
|
|
$this->l('Offer second address'),
|
|
$this->l('In primary address (invoice), show checkbox to expand secondary address (delivery)')
|
|
),
|
|
$this->generateSwitch(
|
|
'expand_second_address',
|
|
$this->l('Auto-expand second address'),
|
|
$this->l('Make both addresses (invoice + delivery) visible right away')
|
|
),
|
|
$this->generateSwitch(
|
|
'mark_required_fields',
|
|
$this->l('Mark required fields (*)'),
|
|
$this->l('Show red star next to required fields label')
|
|
),
|
|
$this->generateSwitch(
|
|
'newsletter_checked',
|
|
$this->l('Newsletter checked by default'),
|
|
$this->l('Newsletter checkbox will be ticked by default - ps_emailsubscription module must be enabled!')
|
|
),
|
|
$this->generateSwitch(
|
|
'show_call_prefix',
|
|
$this->l('Show call prefix'),
|
|
$this->l('Display call prefix number in front of phone number fields - dynamically changed based on selected country')
|
|
),
|
|
$this->generateSwitch(
|
|
'initialize_address',
|
|
$this->l('Initialize Address'),
|
|
$this->l('On initial load, set the address object - enable if your shipping methods depend on address ID or if you use delivery date/time widget')
|
|
),
|
|
$this->generateSwitch(
|
|
'show_button_save_personal_info',
|
|
$this->l('Show "Save" button in Personal Info'),
|
|
$this->l('Display button to save guest/account before showing shipping and payment methods')
|
|
),
|
|
$this->generateSwitch(
|
|
'use_old_address_on_reorder',
|
|
$this->l('Use old address on reorder'),
|
|
$this->l('When customer makes Re-order, use the same address as in original order - do not use his latest address')
|
|
),
|
|
$this->generateText(
|
|
'google_maps_api_key',
|
|
$this->l('Google maps API key'),
|
|
$this->l('API key to enable Google address autocomplete'),
|
|
array(),
|
|
$this->l('Set API key to enable Google address auto-complete')
|
|
),
|
|
$this->generateText(
|
|
'smartform_client_id',
|
|
$this->l('Smartform clientId'),
|
|
$this->l('For Czech/Slovak address auto-complete'),
|
|
array(),
|
|
$this->l('Nastavte ID zákazníka (clientId) ze Smartform administrace (vpravo nahoře)')
|
|
)
|
|
),
|
|
'submit' => array(
|
|
'title' => $this->l('Save'),
|
|
)
|
|
),
|
|
);
|
|
|
|
$enforcedSeparatePaymentModules = array('xps_checkout', 'xbraintreeofficial');
|
|
$separate_payment_required = false;
|
|
foreach ($enforcedSeparatePaymentModules as $moduleName) {
|
|
if (Module::isInstalled($moduleName) && Module::isEnabled($moduleName)) {
|
|
$separate_payment_required = true;
|
|
}
|
|
}
|
|
|
|
$fields_form[] = array(
|
|
'form' => array(
|
|
'tinymce' => true,
|
|
'legend' => array(
|
|
'title' => $this->l('Shipping & Payment'),
|
|
'icon' => 'icon-cogs',
|
|
),
|
|
'input' => array(
|
|
$this->generateSwitch(
|
|
'force_customer_to_choose_country',
|
|
$this->l('Force customer to choose country'),
|
|
$this->l('Hides shipping methods and de-select country at the beginning, so that customer has to choose country manually')
|
|
),
|
|
$this->generateText(
|
|
'shipping_required_fields',
|
|
$this->l('Shipping required fields'),
|
|
$this->l('Comma separated list of fields that need to be filled-in to show shipping options, e.g.: id_state, postcode, city')
|
|
),
|
|
$this->generateSwitch(
|
|
'force_customer_to_choose_carrier',
|
|
$this->l('Force customer to choose carrier'),
|
|
$this->l('De-select default carrier and force customer to make his own selection')
|
|
),
|
|
$this->generateSwitch(
|
|
'show_shipping_country_in_carriers',
|
|
$this->l('Show "shipping to" in carriers'),
|
|
$this->l('Show shipping country name in carriers selection, for better clarity')
|
|
),
|
|
$this->generateSwitch(
|
|
'postcode_remove_spaces',
|
|
$this->l('Remove spaces from postcode'),
|
|
$this->l('When postcode field is modified, inner-spaces are removed automatically')
|
|
),
|
|
$this->generateSwitch(
|
|
'show_order_message',
|
|
$this->l('Show Order Message'),
|
|
$this->l('Show Textarea for arbitrary order message')
|
|
),
|
|
$this->generateSwitch(
|
|
'separate_payment',
|
|
$this->l('Payment options on separate page'),
|
|
$this->l('Final payment options list will be displayed on separate page. Optional for any payment method, but required if you have: [Prestashop Checkout or Braintree Official]'),
|
|
array(),
|
|
($separate_payment_required ? $this->l('Option enforced, because [Prestashop Checkout or Braintree official] payment module is enabled') : ''),
|
|
($separate_payment_required ? 'inactive' : '')
|
|
),
|
|
$this->generateSelect(
|
|
'default_payment_method',
|
|
$this->l('Default payment method'),
|
|
$this->l('Which payment method shall be selected by default'),
|
|
$paymentOptionsCombo
|
|
),
|
|
$this->generateText(
|
|
'payment_required_fields',
|
|
$this->l('Payment required fields'),
|
|
$this->l('Comma separated list of fields that need to be filled-in to show payment options, e.g.: id_state, lastname'),
|
|
array(),
|
|
$this->l('Inactive because "Payment options on separate page" is enabled.'),
|
|
'desc-visible-only-when-inactive'
|
|
),
|
|
$this->generateSwitch(
|
|
'collapse_shipping_methods',
|
|
$this->l('Collapse shipping methods'),
|
|
$this->l('When single shipping method is selected, collapse remaining ones'),
|
|
array()
|
|
),
|
|
$this->generateSwitch(
|
|
'collapse_payment_methods',
|
|
$this->l('Collapse payment methods'),
|
|
$this->l('When single payment method is selected, collapse remaining ones'),
|
|
array()
|
|
),
|
|
$this->generateSwitch(
|
|
'logos_on_the_right',
|
|
$this->l('Shipping/payment logos on the right'),
|
|
$this->l('Show shipping and payment logos on the right side in a listing'),
|
|
array()
|
|
),
|
|
),
|
|
'submit' => array(
|
|
'title' => $this->l('Save')
|
|
)
|
|
),
|
|
);
|
|
$fields_form[] = array(
|
|
'form' => array(
|
|
'tinymce' => true,
|
|
'legend' => array(
|
|
'title' => $this->l('Address fields'),
|
|
'icon' => 'icon-cogs'
|
|
),
|
|
'input' => array(
|
|
array(
|
|
'type' => 'hidden',
|
|
'name' => 'TC_customer_fields'
|
|
),
|
|
array(
|
|
'type' => 'hidden',
|
|
'name' => 'TC_invoice_fields'
|
|
),
|
|
array(
|
|
'type' => 'hidden',
|
|
'name' => 'TC_delivery_fields'
|
|
),
|
|
),
|
|
'submit' => array(
|
|
'title' => $this->l('Save')
|
|
)
|
|
),
|
|
);
|
|
$fields_form[] = array(
|
|
'form' => array(
|
|
'tinymce' => true,
|
|
'legend' => array(
|
|
'title' => $this->l('Layout'),
|
|
'icon' => 'icon-cogs'
|
|
),
|
|
'input' => array(
|
|
array(
|
|
'type' => 'hidden',
|
|
'name' => 'TC_blocks_layout'
|
|
),
|
|
$this->generateSwitch(
|
|
'move_login_to_account',
|
|
$this->l('Move login to account block'),
|
|
$this->l('Displays log-in offer at the top of account block'),
|
|
array()
|
|
),
|
|
array(
|
|
'type' => 'textarea',
|
|
'label' => $this->l('HTML Box No.1'),
|
|
'name' => 'TC_html_box_1',
|
|
'lang' => true,
|
|
'autoload_rte' => '', //'rte' = enable TinyMCE editor, empty = not enabled
|
|
'class' => 'tinymce-on-demand',
|
|
'col' => 8,
|
|
'hint' => $this->trans('Invalid characters:', array(),
|
|
'Admin.Notifications.Info') . ' <>;=#{}'
|
|
),
|
|
array(
|
|
'type' => 'textarea',
|
|
'label' => $this->l('HTML Box No.2'),
|
|
'name' => 'TC_html_box_2',
|
|
'lang' => true,
|
|
'autoload_rte' => '', //'rte' = enable TinyMCE editor, empty = not enabled
|
|
'class' => 'tinymce-on-demand',
|
|
'col' => 8,
|
|
'hint' => $this->trans('Invalid characters:', array(),
|
|
'Admin.Notifications.Info') . ' <>;=#{}'
|
|
),
|
|
array(
|
|
'type' => 'textarea',
|
|
'label' => $this->l('HTML Box No.3'),
|
|
'name' => 'TC_html_box_3',
|
|
'lang' => true,
|
|
'autoload_rte' => '', //'rte' = enable TinyMCE editor, empty = not enabled
|
|
'class' => 'tinymce-on-demand',
|
|
'col' => 8,
|
|
'hint' => $this->trans('Invalid characters:', array(),
|
|
'Admin.Notifications.Info') . ' <>;=#{}'
|
|
),
|
|
array(
|
|
'type' => 'textarea',
|
|
'label' => $this->l('HTML Box No.4'),
|
|
'name' => 'TC_html_box_4',
|
|
'lang' => true,
|
|
'autoload_rte' => '', //'rte' = enable TinyMCE editor, empty = not enabled
|
|
'class' => 'tinymce-on-demand',
|
|
'col' => 8,
|
|
'hint' => $this->trans('Invalid characters:', array(),
|
|
'Admin.Notifications.Info') . ' <>;=#{}'
|
|
),
|
|
array(
|
|
'type' => 'textarea',
|
|
'label' => $this->l('Required Checkbox No.1'),
|
|
'name' => 'TC_required_checkbox_1',
|
|
'desc' => 'To enable a required checkbox in checkout page, fill-in the checkbox label here. You can add label also with link, for example: ' . $this->tagIt('br') . $this->tagIt('b', 'I agree with <a href="content/3-privacy-policy">privacy policy</a>'),
|
|
'lang' => true,
|
|
'autoload_rte' => '', //'rte' = enable TinyMCE editor, empty = not enabled
|
|
'class' => 'tinymce-on-demand',
|
|
'col' => 8,
|
|
'hint' => $this->trans(
|
|
'Arbitrary checkbox that user needs to confirm to proceed with order, fill in text to enable.',
|
|
array(),
|
|
'Admin.Notifications.Info'
|
|
)
|
|
),
|
|
array(
|
|
'type' => 'textarea',
|
|
'label' => $this->l('Required Checkbox No.2'),
|
|
'name' => 'TC_required_checkbox_2',
|
|
'lang' => true,
|
|
'autoload_rte' => '', //'rte' = enable TinyMCE editor, empty = not enabled
|
|
'class' => 'tinymce-on-demand',
|
|
'col' => 8,
|
|
'hint' => $this->trans(
|
|
'Arbitrary checkbox that user needs to confirm to proceed with order, fill in text to enable.',
|
|
array(),
|
|
'Admin.Notifications.Info'
|
|
)
|
|
),
|
|
),
|
|
|
|
'submit' => array(
|
|
'title' => $this->l('Save')
|
|
)
|
|
),
|
|
);
|
|
$fields_form[] = array(
|
|
'form' => array(
|
|
'legend' => array(
|
|
'title' => $this->l('Steps'),
|
|
'icon' => 'icon-cogs',
|
|
'top' => 'top text, free...'
|
|
),
|
|
'input' => array(
|
|
$this->generateSwitch(
|
|
'checkout_steps',
|
|
$this->l('Checkout steps'),
|
|
$this->l('Enable virtual steps'), array(),
|
|
$this->l('Leave \'Label\' empty if you wish to disable particular step below') .
|
|
$this->tagIt('div', $this->tagIt('a', $this->l('Click to set Starting configuration sample'),
|
|
'data-confirm-msg="'. $this->l('Are you sure? This will change blocks layout and also add custom CSS rules.').'"'),
|
|
'id="set-steps-sample"')
|
|
),
|
|
// Step 1
|
|
$this->generateText(
|
|
'step_label_1',
|
|
$this->l('Label'),
|
|
$this->l('Step 1 label, multi-language field'),
|
|
array(), '', 'config-step-1', true
|
|
),
|
|
$this->generateText(
|
|
'step_blocks_1',
|
|
$this->l('Visible blocks'),
|
|
$this->l('Comma separated list of blocks visible in this step'),
|
|
array(), '', 'config-step-1'
|
|
),
|
|
// Step 2
|
|
$this->generateText(
|
|
'step_label_2',
|
|
$this->l('Label'),
|
|
$this->l('Step 2 label, multi-language field'),
|
|
array(), '', 'config-step-2', true
|
|
),
|
|
$this->generateText(
|
|
'step_blocks_2',
|
|
$this->l('Visible blocks'),
|
|
$this->l('Comma separated list of blocks visible in this step'),
|
|
array(), '', 'config-step-2'
|
|
),
|
|
array(
|
|
'type' => 'textarea',
|
|
'label' => $this->l('Validation expression (JS)'),
|
|
'name' => 'TC_step_validation_2',
|
|
'lang' => false,
|
|
'cols' => 60,
|
|
'rows' => 1,
|
|
'autoload_rte' => false, //Enable TinyMCE editor for short description
|
|
'col' => 6,
|
|
'hint' => $this->l('JS validation expression required to reach this step'),
|
|
'class' => 'max-size',
|
|
'form_group_class' => 'config-step-2'
|
|
),
|
|
$this->generateText(
|
|
'step_validation_error_2',
|
|
$this->l('Error message'),
|
|
$this->l('Error shown to user when validation to reach this step fails'),
|
|
array(), '', 'config-step-2', true
|
|
),
|
|
// Step 3
|
|
$this->generateText(
|
|
'step_label_3',
|
|
$this->l('Label'),
|
|
$this->l('Step 3 label, multi-language field'),
|
|
array(), '', 'config-step-3', true
|
|
),
|
|
$this->generateText(
|
|
'step_blocks_3',
|
|
$this->l('Visible blocks'),
|
|
$this->l('Comma separated list of blocks visible in this step'),
|
|
array(), '', 'config-step-3', false
|
|
),
|
|
array(
|
|
'type' => 'textarea',
|
|
'label' => $this->l('Validation expression (JS)'),
|
|
'name' => 'TC_step_validation_3',
|
|
'lang' => false,
|
|
'cols' => 60,
|
|
'rows' => 1,
|
|
'autoload_rte' => false, //Enable TinyMCE editor for short description
|
|
'col' => 6,
|
|
'hint' => $this->l('JS validation expression required to reach this step'),
|
|
'class' => 'max-size',
|
|
'form_group_class' => 'config-step-3'
|
|
),
|
|
$this->generateText(
|
|
'step_validation_error_3',
|
|
$this->l('Error message'),
|
|
$this->l('Error shown to user when validation to reach this step fails'),
|
|
array(), '', 'config-step-3', true
|
|
),
|
|
// Step 4
|
|
$this->generateText(
|
|
'step_label_4',
|
|
$this->l('Label'),
|
|
$this->l('Step 4 label, multi-language field'),
|
|
array(), '', 'config-step-4', true
|
|
),
|
|
$this->generateText(
|
|
'step_blocks_4',
|
|
$this->l('Visible blocks'),
|
|
$this->l('Comma separated list of blocks visible in this step'),
|
|
array(), '', 'config-step-4', false
|
|
),
|
|
array(
|
|
'type' => 'textarea',
|
|
'label' => $this->l('Validation expression (JS)'),
|
|
'name' => 'TC_step_validation_4',
|
|
'lang' => false,
|
|
'cols' => 60,
|
|
'rows' => 1,
|
|
'autoload_rte' => false, //Enable TinyMCE editor for short description
|
|
'col' => 6,
|
|
'hint' => $this->l('JS validation rules for this step'),
|
|
'class' => 'max-size',
|
|
'form_group_class' => 'config-step-4'
|
|
),
|
|
$this->generateText(
|
|
'step_validation_error_4',
|
|
$this->l('Error message'),
|
|
$this->l('Error shown to user when validation to reach this step fails'),
|
|
array(), '', 'config-step-4', true
|
|
),
|
|
),
|
|
|
|
'submit' => array(
|
|
'title' => $this->l('Save')
|
|
)
|
|
),
|
|
);
|
|
$fields_form[] = array(
|
|
'form' => array(
|
|
'tinymce' => true,
|
|
'legend' => array(
|
|
'title' => $this->l('Social login'),
|
|
'icon' => 'icon-cogs'
|
|
),
|
|
'input' => array(
|
|
$this->generateSwitch(
|
|
'social_login_fb',
|
|
$this->l('Facebook Login'),
|
|
$this->l('Enable Facebook Login')
|
|
),
|
|
$this->generateText(
|
|
'social_login_fb_app_id',
|
|
$this->l('Facebook App ID'),
|
|
$this->l('App ID from Facebook developers API')
|
|
),
|
|
$this->generateText(
|
|
'social_login_fb_app_secret',
|
|
$this->l('Facebook App Secret'),
|
|
$this->l('App Secret from Facebook developers API')
|
|
),
|
|
$this->generateSwitch(
|
|
'social_login_google',
|
|
$this->l('Google Sign-In'),
|
|
$this->l('Enable Google Sign-In')
|
|
),
|
|
$this->generateText(
|
|
'social_login_google_client_id',
|
|
$this->l('Google Client ID'),
|
|
$this->l('Client ID from Google developers API')
|
|
),
|
|
$this->generateText(
|
|
'social_login_google_client_secret',
|
|
$this->l('Google Client Secret'),
|
|
$this->l('Client Secret from Google developers API')
|
|
),
|
|
// $this->generateSelect(
|
|
// 'social_login_btn_style',
|
|
// $this->l('Style of login buttons'),
|
|
// $this->l('Pre-defined styles, choose one and make further customizations in CSS files'),
|
|
// array(
|
|
// array('id' => 'light', 'name' => 'Light theme'),
|
|
// array('id' => 'bootstrap', 'name' => 'Bootstrap, full colors')
|
|
// )
|
|
// ),
|
|
$this->generateSwitch(
|
|
'social_login_display_on_login_page',
|
|
$this->l('Display also on PS login page'),
|
|
$this->l('Social login buttons will be shown also on Prestashop default login page')
|
|
)
|
|
// $this->generateSwitch(
|
|
// 'paypal_express_checkout',
|
|
// $this->l('Paypal express checkout'),
|
|
// $this->l('Show Paypal express checkout button in Sign-in area'),
|
|
// array(),
|
|
// $this->l('Inactive because Paypal module is NOT enabled.'),
|
|
// 'desc-visible-only-when-inactive'
|
|
// )
|
|
),
|
|
|
|
'submit' => array(
|
|
'title' => $this->l('Save')
|
|
)
|
|
),
|
|
);
|
|
$fields_form[] = array(
|
|
'form' => array(
|
|
'tinymce' => true,
|
|
'legend' => array(
|
|
'title' => $this->l('Advanced'),
|
|
'icon' => 'icon-cogs'
|
|
),
|
|
'input' => array(
|
|
// $this->generateSwitch(
|
|
// 'refresh_minicart',
|
|
// $this->l('Refresh mini-cart'),
|
|
// $this->l('On each cart update, also updata mini-cart (available for some themes only)')
|
|
// ),
|
|
$this->generateSwitch(
|
|
'clean_checkout_session_after_confirmation',
|
|
$this->l('Clean checkout session'),
|
|
$this->l('Clean remembered status of checkboxes (Terms & conditions, Customer privacy, ...) after order is confirmed')
|
|
),
|
|
$this->generateSwitch(
|
|
'assign_customer_id_asap',
|
|
$this->l('Assign Address to Customer ASAP'),
|
|
$this->l('Even when Address is not yet fully filled-in, assign it to Customer as soon as possible')
|
|
),
|
|
$this->generateText(
|
|
'ps_css_cache_version',
|
|
$this->l('PS CSS cache version'),
|
|
$this->l('Increase if changes in CSS files do not reflect on frontend')
|
|
),
|
|
$this->generateText(
|
|
'ps_js_cache_version',
|
|
$this->l('PS JS cache version'),
|
|
$this->l('Increase if changes in JS files do not reflect on frontend')
|
|
),
|
|
// 30.7.2021 - setting auto_render to false is not necessary anymore due to improvements in PS Checkout payment module.
|
|
// $this->generateSwitch(
|
|
// 'ps_checkout_auto_render_disabled',
|
|
// $this->l('PS Checkout Auto Render Disabled'),
|
|
// $this->l('Set ps_checkout_auto_render_disabled option')
|
|
// ),
|
|
array(
|
|
'type' => 'textarea',
|
|
'label' => $this->l('Custom CSS'),
|
|
'name' => 'TC_custom_css',
|
|
'lang' => false,
|
|
'cols' => 60,
|
|
'rows' => 7,
|
|
'autoload_rte' => false, //Enable TinyMCE editor for short description
|
|
'col' => 6,
|
|
'hint' => $this->l('Custom CSS used on checkout page'),
|
|
'class' => 'max-size-lg'
|
|
),
|
|
array(
|
|
'type' => 'textarea',
|
|
'label' => $this->l('Custom JS'),
|
|
'name' => 'TC_custom_js',
|
|
'lang' => false,
|
|
'cols' => 60,
|
|
'rows' => 7,
|
|
'autoload_rte' => false, //Enable TinyMCE editor for short description
|
|
'col' => 6,
|
|
'hint' => $this->l('Custom JS, (!) consider that jQuery might be loaded later, use it only in plain JS DOMready handler!'),
|
|
'class' => 'max-size-lg',
|
|
// Generate reset link markup through description of this very last config element
|
|
'desc' => $this->tagIt('div',$this->l('Reset ALL SETTINGS to default values') . ': '. $this->tagIt('span', '', 'class="reset-link" data-section="ALL SETTINGS" data-action="resetAllSettings"'),
|
|
'id="reset-all-settings"')
|
|
),
|
|
),
|
|
|
|
'submit' => array(
|
|
'title' => $this->l('Save')
|
|
)
|
|
),
|
|
);
|
|
|
|
return $fields_form;
|
|
}
|
|
|
|
/**
|
|
* Set values for the inputs.
|
|
*/
|
|
protected function getConfigFormValues()
|
|
{
|
|
$tc_options = $this->config->getAllOptions('TC_', true);
|
|
|
|
// hide sensitive data in demo
|
|
if ('demo@demo.com' == $this->context->employee->email) {
|
|
$tc_options['TC_social_login_fb_app_secret'] = '200775a7d7b096e5d2f12c2b1aab9a87';
|
|
$tc_options['TC_social_login_google_client_secret'] = 'K0hWjDCblEGcMwTqEjr-HbdF';
|
|
}
|
|
|
|
$other_options = array(
|
|
'XYZ_LIVE_MODE' => Configuration::get('XYZ_LIVE_MODE', true)
|
|
);
|
|
|
|
$languages = Language::getLanguages(false);
|
|
$fields_localized = array();
|
|
$fields_localized_names = array(
|
|
'TC_html_box_1',
|
|
'TC_html_box_2',
|
|
'TC_html_box_3',
|
|
'TC_html_box_4',
|
|
'TC_required_checkbox_1',
|
|
'TC_required_checkbox_2',
|
|
'TC_step_label_1',
|
|
'TC_step_label_2',
|
|
'TC_step_label_3',
|
|
'TC_step_label_4',
|
|
'TC_step_validation_error_2',
|
|
'TC_step_validation_error_3',
|
|
'TC_step_validation_error_4'
|
|
);
|
|
foreach ($languages as $lang) {
|
|
foreach ($fields_localized_names as $name) {
|
|
$fields_localized[$name][(int)$lang['id_lang']] = Tools::getValue(
|
|
$name . (int)$lang['id_lang'],
|
|
Configuration::get($name, (int)$lang['id_lang'])
|
|
);
|
|
}
|
|
|
|
}
|
|
return array_merge($tc_options, $other_options, $fields_localized);
|
|
}
|
|
|
|
/**
|
|
* Save form data.
|
|
*/
|
|
protected function postProcess()
|
|
{
|
|
//if ('demo@demo.com' == $this->context->employee->email) {
|
|
// return 'This is DEMO store, set in read-only mode, settings cannot be updated.';
|
|
//}
|
|
$errors = '';
|
|
|
|
$form_values = array_merge($this->config->getAllOptions(''), array(
|
|
'XYZ_LIVE_MODE' => Configuration::get('XYZ_LIVE_MODE', true),
|
|
));
|
|
|
|
foreach (array_keys($form_values) as $key) {
|
|
|
|
$errors .= $this->config->updateByName($key);
|
|
//echo "updating $key with: ".Tools::getValue($key)."\n\n";
|
|
}
|
|
|
|
return $errors;
|
|
}
|
|
}
|