827 lines
29 KiB
PHP
827 lines
29 KiB
PHP
<?php
|
|
/**
|
|
* Copyright (C) 2020 Futurenext srl
|
|
*
|
|
* This file is part of Zakeke.
|
|
*
|
|
* Zakeke Interactive Product Designer can not be copied and/or distributed
|
|
* without the express permission of Futurenext srl
|
|
*
|
|
* @author Futurenext srl <help@zakeke.com>
|
|
* @copyright 2019 Futurenext srl
|
|
* @license https://www.zakeke.com/privacy/#general_conditions
|
|
*/
|
|
|
|
if (!defined('_PS_VERSION_')) {
|
|
exit;
|
|
}
|
|
|
|
include_once dirname(__FILE__) . '/webservice/WebserviceSpecificManagementZakekeCurrency.php';
|
|
include_once dirname(__FILE__) . '/classes/ZakekeEnabled.php';
|
|
include_once dirname(__FILE__) . '/classes/ZakekeConfiguratorEnabled.php';
|
|
include_once dirname(__FILE__) . '/classes/ZakekeApi.php';
|
|
include_once dirname(__FILE__) . '/classes/ZakekeItem.php';
|
|
include_once dirname(__FILE__) . '/classes/ZakekeConfiguratorItem.php';
|
|
include_once dirname(__FILE__) . '/classes/ZakekePrice.php';
|
|
include_once dirname(__FILE__) . '/classes/ZakekeCompatibility.php';
|
|
include_once dirname(__FILE__) . '/classes/ZakekeOrderService.php';
|
|
include_once dirname(__FILE__) . '/classes/ZakekeDisplayCustomization.php';
|
|
include_once dirname(__FILE__) . '/classes/ZakekeWebserviceService.php';
|
|
include_once dirname(__FILE__) . '/classes/ZakekeConnectService.php';
|
|
include_once dirname(__FILE__) . '/classes/ZakekeEditUrl.php';
|
|
|
|
define('ZAKEKE_VERSION', '3.2.9');
|
|
|
|
class Zakeke extends Module
|
|
{
|
|
/** @var ZakekeApi */
|
|
protected $zakekeApi;
|
|
|
|
/** @var bool */
|
|
private $cart_action_is_executing = false;
|
|
|
|
/** @var bool */
|
|
private $order_resend_is_executing = false;
|
|
|
|
/**
|
|
* Zakeke constructor.
|
|
*/
|
|
public function __construct()
|
|
{
|
|
$this->name = 'zakeke';
|
|
$this->tab = 'front_office_features';
|
|
$this->version = '3.2.9';
|
|
$this->author = 'Futurenext srl';
|
|
$this->need_instance = 0;
|
|
$this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
|
|
$this->bootstrap = true;
|
|
|
|
$this->module_key = '8b06b71e6e82c5824a020e70178a4e1a';
|
|
|
|
parent::__construct();
|
|
|
|
$this->displayName = $this->l('Zakeke Interactive Product Designer');
|
|
$this->description = $this->l(
|
|
'Innovative platforms to enable your customers with live product customization on your e-store.'
|
|
);
|
|
|
|
$this->confirmUninstall = $this->l('Are you sure you want to uninstall?');
|
|
|
|
if (!$this->hasAccountConnected()) {
|
|
$this->warning = $this->l('You must set your Zakeke credentials');
|
|
}
|
|
|
|
$this->zakekeApi = new ZakekeApi($this->isDebugModeActive());
|
|
|
|
if (!$this->isRegisteredInHook('actionCartSave')) {
|
|
$this->registerHook('actionCartSave');
|
|
}
|
|
|
|
if (!$this->isRegisteredInHook('actionObjectProductInCartDeleteBefore')) {
|
|
$this->registerHook('actionObjectProductInCartDeleteBefore');
|
|
}
|
|
|
|
if (!$this->isRegisteredInHook('actionAdminControllerSetMedia')) {
|
|
$this->registerHook('actionAdminControllerSetMedia');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if the module has all necessary data to work properly
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function hasAccountConnected()
|
|
{
|
|
return Configuration::get('ZAKEKE_API_CLIENT_ID') &&
|
|
Configuration::get('ZAKEKE_API_SECRET_KEY');
|
|
}
|
|
|
|
/**
|
|
* Check if Zakeke is in debug mode.
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function isDebugModeActive()
|
|
{
|
|
$debug = Configuration::get('ZAKEKE_DEBUG');
|
|
|
|
return $debug && $debug == 'yes';
|
|
}
|
|
|
|
/**
|
|
* Check if Zakeke is forcing the product customization
|
|
*
|
|
* @return bool
|
|
*/
|
|
protected function isForceActive()
|
|
{
|
|
$zakekeForce = Configuration::get('ZAKEKE_FORCE');
|
|
|
|
return $zakekeForce == 1;
|
|
}
|
|
|
|
/**
|
|
* Get an instance of the Zakeke API.
|
|
*
|
|
* @return ZakekeApi
|
|
*/
|
|
public function getZakekeApi()
|
|
{
|
|
return $this->zakekeApi;
|
|
}
|
|
|
|
/**
|
|
* Get an identifier for the Zakeke guest
|
|
*
|
|
* @param bool $create Create a Zakeke guest cookie if not present
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getZakekeGuestCode($create = true)
|
|
{
|
|
$guestCode = $this->context->cookie->zakeke_guest;
|
|
if ($create && !$guestCode) {
|
|
if (_PS_VERSION_ < 1.7) {
|
|
$guestCode = Tools::passwdGen(90, 'RANDOM');
|
|
} else {
|
|
$guestCode = PhpEncryption::createNewRandomKey();
|
|
}
|
|
|
|
$this->context->cookie->zakeke_guest = $guestCode;
|
|
$this->context->cookie->write();
|
|
}
|
|
|
|
return Tools::substr($guestCode, 0, 90);
|
|
}
|
|
|
|
public function displayForm()
|
|
{
|
|
// Get default language
|
|
$default_lang = (int)Configuration::get('PS_LANG_DEFAULT');
|
|
|
|
// Init Fields form array
|
|
$fields_form = array();
|
|
|
|
$fields_form[] = array(
|
|
'form' => array(
|
|
'legend' => array(
|
|
'title' => $this->l('Zakeke API keys'),
|
|
),
|
|
'input' => array(
|
|
array(
|
|
'type' => 'text',
|
|
'label' => $this->l('Zakeke API Client ID'),
|
|
'name' => 'ZAKEKE_API_CLIENT_ID',
|
|
'desc' => vsprintf(
|
|
$this->l('Your Zakeke account API. Need a Zakeke account? %sClick here to get one%s'),
|
|
array('<a href="https://portal.zakeke.com/Admin/Register" target="_blank">', '</a>')
|
|
),
|
|
'required' => true,
|
|
'class' => 'fixed-width-xl'
|
|
),
|
|
array(
|
|
'type' => 'password',
|
|
'label' => $this->l('Zakeke API Secret Key'),
|
|
'name' => 'ZAKEKE_API_SECRET_KEY',
|
|
'desc' => $this->l('Your Zakeke account API secret key.'),
|
|
'required' => true,
|
|
'class' => 'fixed-width-xl'
|
|
)
|
|
),
|
|
'submit' => array(
|
|
'title' => $this->l('Save'),
|
|
'class' => 'btn btn-default pull-right',
|
|
'name' => 'ZAKEKE_SAVE_CREDENTIALS'
|
|
)
|
|
)
|
|
);
|
|
|
|
$fields_form[] = array(
|
|
'form' => array(
|
|
'legend' => array(
|
|
'title' => $this->l('Settings'),
|
|
),
|
|
'input' => array(
|
|
array(
|
|
'type' => 'switch',
|
|
'label' => $this->l('Force product customization'),
|
|
'name' => 'ZAKEKE_FORCE',
|
|
'desc' => $this->l(
|
|
'Your customers will be forced to customize the product before adding it to cart.'
|
|
),
|
|
'align' => 'center',
|
|
'active' => 'status',
|
|
'orderby' => false,
|
|
'class' => 'fixed-width-xs',
|
|
'values' => array(
|
|
array(
|
|
'id' => 'active_on',
|
|
'value' => 1,
|
|
'label' => $this->l('Enabled')
|
|
),
|
|
array(
|
|
'id' => 'active_off',
|
|
'value' => 0,
|
|
'label' => $this->l('Disabled')
|
|
)
|
|
),
|
|
)
|
|
),
|
|
'submit' => array(
|
|
'title' => $this->l('Save'),
|
|
'class' => 'btn btn-default pull-right',
|
|
'name' => 'ZAKEKE_SAVE_SETTINGS'
|
|
)
|
|
)
|
|
);
|
|
|
|
$helper = new HelperForm();
|
|
|
|
// Module, token and currentIndex
|
|
$helper->module = $this;
|
|
$helper->name_controller = $this->name;
|
|
$helper->token = Tools::getAdminTokenLite('AdminModules');
|
|
$helper->currentIndex = AdminController::$currentIndex . '&configure=' . $this->name;
|
|
|
|
// Language
|
|
$helper->default_form_language = $default_lang;
|
|
$helper->allow_employee_form_lang = $default_lang;
|
|
|
|
// Title and toolbar
|
|
$helper->title = $this->displayName;
|
|
$helper->show_toolbar = true; // false -> remove toolbar
|
|
$helper->toolbar_scroll = true; // yes - > Toolbar is always visible on the top of the screen.
|
|
$helper->submit_action = 'submit' . $this->name;
|
|
$helper->toolbar_btn = array(
|
|
'save' =>
|
|
array(
|
|
'desc' => $this->l('Save'),
|
|
'href' => AdminController::$currentIndex . '&configure=' . $this->name . '&save' . $this->name .
|
|
'&token=' . Tools::getAdminTokenLite('AdminModules'),
|
|
),
|
|
'back' => array(
|
|
'href' => AdminController::$currentIndex . '&token=' . Tools::getAdminTokenLite('AdminModules'),
|
|
'desc' => $this->l('Back to list')
|
|
)
|
|
);
|
|
|
|
// Load current value
|
|
$helper->fields_value['ZAKEKE_API_CLIENT_ID'] = Configuration::get('ZAKEKE_API_CLIENT_ID');
|
|
$helper->fields_value['ZAKEKE_API_SECRET_KEY'] = Configuration::get('ZAKEKE_API_SECRET_KEY');
|
|
$helper->fields_value['ZAKEKE_FORCE'] = Configuration::get('ZAKEKE_FORCE');
|
|
|
|
return $helper->generateForm($fields_form);
|
|
}
|
|
|
|
public function getContent()
|
|
{
|
|
$output = '';
|
|
|
|
if (Tools::isSubmit('ZAKEKE_SAVE_CREDENTIALS')) {
|
|
$zakekeApiClientId = (string)Tools::getValue('ZAKEKE_API_CLIENT_ID');
|
|
$zakekeApiSecretKey = (string)Tools::getValue('ZAKEKE_API_SECRET_KEY');
|
|
|
|
if (empty($zakekeApiClientId) && empty($zakekeApiSecretKey)) {
|
|
$zakekeApiClientId = '';
|
|
$zakekeApiSecretKey = '';
|
|
} elseif (empty($zakekeApiClientId) || empty($zakekeApiSecretKey)) {
|
|
$zakekeApiClientId = '';
|
|
$zakekeApiSecretKey = '';
|
|
$output .= $this->displayError($this->l('Zakeke API Client ID and Secret Key must not be empty'));
|
|
} else {
|
|
if (!$this->getZakekeApi()->checkCredentials($zakekeApiClientId, $zakekeApiSecretKey)) {
|
|
$zakekeApiClientId = '';
|
|
$zakekeApiSecretKey = '';
|
|
$output .= $this->displayError($this->l('Invalid Zakeke API keys'));
|
|
} else {
|
|
$output .= $this->displayConfirmation($this->l('Zakeke API keys updated'));
|
|
}
|
|
}
|
|
|
|
Configuration::updateValue('ZAKEKE_API_CLIENT_ID', $zakekeApiClientId);
|
|
Configuration::updateValue('ZAKEKE_API_SECRET_KEY', $zakekeApiSecretKey);
|
|
} elseif (Tools::isSubmit('ZAKEKE_SAVE_SETTINGS')) {
|
|
$zakekeForce = (string)Tools::getValue('ZAKEKE_FORCE');
|
|
|
|
if ($zakekeForce != 0 && $zakekeForce != 1) {
|
|
$output .= $this->displayError($this->l('Invalid or empty value for force customization'));
|
|
} else {
|
|
$output .= $this->displayConfirmation($this->l('Settings updated'));
|
|
}
|
|
|
|
Configuration::updateValue('ZAKEKE_FORCE', $zakekeForce);
|
|
}
|
|
|
|
if (empty(Configuration::get('ZAKEKE_API_CLIENT_ID')) || empty(Configuration::get('ZAKEKE_API_CLIENT_ID'))) {
|
|
ZakekeWebserviceService::enableWebservice();
|
|
$zakekeWebserviceKey = ZakekeWebserviceService::getOrCreateZakekeWebServiceKey();
|
|
$this->smarty->assign(array(
|
|
'zakeke_connect_url' => ZakekeConnectService::getConnectUrl($zakekeWebserviceKey),
|
|
'zakeke_showall_url' => $_SERVER['REQUEST_URI'] . '&showall=1'
|
|
));
|
|
$output .= $this->display(__FILE__, 'infos.tpl');
|
|
|
|
if (Tools::getValue('showall', false)) {
|
|
$output .= $this->displayForm();
|
|
}
|
|
} else {
|
|
$output .= $this->displayForm();
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Register the Zakeke WS endpoint
|
|
*
|
|
* @param array $params
|
|
*
|
|
* @return array
|
|
*/
|
|
public function hookAddWebserviceResources($params)
|
|
{
|
|
return array(
|
|
'zakeke_currency' => array(
|
|
'description' => 'ZakekeCurrency',
|
|
'specific_management' => true,
|
|
'forbidden_method' => array('POST', 'PUT', 'DELETE', 'HEAD')
|
|
),
|
|
'zakeke_enabled_list' => array('description' => 'Zakeke enabled products', 'class' => 'ZakekeEnabled'),
|
|
'zakeke_configurator_enabled_list' => array(
|
|
'description' => 'Zakeke configurator enabled products',
|
|
'class' => 'ZakekeConfiguratorEnabled'
|
|
)
|
|
);
|
|
}
|
|
|
|
private function customizerHookDisplayHeaderPS16()
|
|
{
|
|
$customizeButtonLabel = $this->l('Customize');
|
|
$zakekeAddUrl = $this->context->link->getModuleLink('zakeke', 'customizer');
|
|
|
|
Media::addJsDef(array(
|
|
'zakekeCustomizeLabel' => addcslashes($customizeButtonLabel, "'"),
|
|
'zakekeAddUrl' => addcslashes($zakekeAddUrl, "'")
|
|
));
|
|
|
|
if ($this->isForceActive()) {
|
|
$this->context->controller->addJS(
|
|
$this->_path . '/views/js/ps16/product-page-force.js'
|
|
);
|
|
} else {
|
|
$this->context->controller->addJS(
|
|
$this->_path . '/views/js/ps16/product-page.js'
|
|
);
|
|
}
|
|
}
|
|
|
|
private function configuratorHookDisplayHeaderPS16()
|
|
{
|
|
$customizeButtonLabel = $this->l('Configure');
|
|
$zakekeConfiguratorAddUrl = $this->context->link->getModuleLink('zakeke', 'configurator');
|
|
|
|
Media::addJsDef(array(
|
|
'zakekeConfigureLabel' => addcslashes($customizeButtonLabel, "'"),
|
|
'zakekeConfiguratorAddUrl' => addcslashes($zakekeConfiguratorAddUrl, "'")
|
|
));
|
|
|
|
if ($this->isForceActive()) {
|
|
$this->context->controller->addJS(
|
|
$this->_path . '/views/js/ps16/configurator/product-page-force.js'
|
|
);
|
|
} else {
|
|
$this->context->controller->addJS(
|
|
$this->_path . '/views/js/ps16/configurator/product-page.js'
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add the Zakeke elements inside the product page of customizable products for PS 1.6
|
|
*/
|
|
public function hookDisplayHeaderPS16()
|
|
{
|
|
try {
|
|
$this->context->controller->addJS(
|
|
$this->_path . '/views/js/ps16/update.js'
|
|
);
|
|
|
|
$zakekeInfoUrl = $this->context->link->getModuleLink('zakeke', 'info');
|
|
Media::addJsDef(array(
|
|
'zakekeInfoUrl' => addcslashes($zakekeInfoUrl, "'")
|
|
));
|
|
|
|
if (!method_exists($this->context->controller, 'getProduct')) {
|
|
return;
|
|
}
|
|
|
|
$product = $this->context->controller->getProduct();
|
|
|
|
if (!$product) {
|
|
return;
|
|
}
|
|
|
|
$zakekeEnabledId = ZakekeEnabled::productEnabledId($product->id);
|
|
if ($zakekeEnabledId !== false) {
|
|
$this->customizerHookDisplayHeaderPS16();
|
|
}
|
|
|
|
$zakekeConfiguratorEnabledId = ZakekeConfiguratorEnabled::productEnabledId($product->id);
|
|
if ($zakekeConfiguratorEnabledId !== false) {
|
|
$this->configuratorHookDisplayHeaderPS16();
|
|
}
|
|
} catch (Exception $e) {
|
|
PrestaShopLogger::addLog('Zakeke hookDisplayHeader Call error: ' . $e);
|
|
$this->context->controller->errors[] = $this->l('Zakeke failed to initialize');
|
|
}
|
|
}
|
|
|
|
private function customizerHookDisplayHeaderPS17()
|
|
{
|
|
$zakekeAddUrl = $this->context->link->getModuleLink('zakeke', 'customizer');
|
|
$customizeButtonLabel = $this->l('Customize');
|
|
|
|
Media::addJsDef(array(
|
|
'zakekeAddUrl' => addcslashes($zakekeAddUrl, "'"),
|
|
'zakekeCustomizeLabel' => addcslashes($customizeButtonLabel, "'")
|
|
));
|
|
|
|
if ($this->isForceActive()) {
|
|
$this->context->controller->registerJavascript(
|
|
'modules-zakake-product-page',
|
|
'modules/' . $this->name . '/views/js/product-page-force.js',
|
|
array('position' => 'bottom', 'priority' => 150)
|
|
);
|
|
} else {
|
|
$this->context->controller->registerJavascript(
|
|
'modules-zakake-product-page',
|
|
'modules/' . $this->name . '/views/js/product-page.js',
|
|
array('position' => 'bottom', 'priority' => 150)
|
|
);
|
|
}
|
|
}
|
|
|
|
private function configuratorHookDisplayHeaderPS17()
|
|
{
|
|
$configureButtonLabel = $this->l('Configure');
|
|
$zakekeConfiguratorAddUrl = $this->context->link->getModuleLink('zakeke', 'configurator');
|
|
|
|
Media::addJsDef(array(
|
|
'zakekeConfigureLabel' => addcslashes($configureButtonLabel, "'"),
|
|
'zakekeConfiguratorAddUrl' => addcslashes($zakekeConfiguratorAddUrl, "'")
|
|
));
|
|
|
|
if ($this->isForceActive()) {
|
|
$this->context->controller->registerJavascript(
|
|
'modules-zakake-configurator-product-page',
|
|
'modules/' . $this->name . '/views/js/configurator/product-page-force.js',
|
|
array('position' => 'bottom', 'priority' => 150)
|
|
);
|
|
} else {
|
|
$this->context->controller->registerJavascript(
|
|
'modules-zakake-configurator-product-page',
|
|
'modules/' . $this->name . '/views/js/configurator/product-page.js',
|
|
array('position' => 'bottom', 'priority' => 150)
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add the Zakeke elements inside the product page of customizable products
|
|
*/
|
|
public function hookDisplayHeaderPS17()
|
|
{
|
|
try {
|
|
if (!method_exists($this->context->controller, 'getProduct')) {
|
|
return;
|
|
}
|
|
|
|
$product = $this->context->controller->getProduct();
|
|
if (!$product) {
|
|
return;
|
|
}
|
|
|
|
$zakekeEnabledId = ZakekeEnabled::productEnabledId($product->id);
|
|
if ($zakekeEnabledId !== false) {
|
|
$this->customizerHookDisplayHeaderPS17();
|
|
}
|
|
|
|
$zakekeConfiguratorEnabledId = ZakekeConfiguratorEnabled::productEnabledId($product->id);
|
|
if ($zakekeConfiguratorEnabledId !== false) {
|
|
$this->configuratorHookDisplayHeaderPS17();
|
|
}
|
|
} catch (Exception $e) {
|
|
PrestaShopLogger::addLog('Zakeke hookDisplayHeader Call error: ' . $e);
|
|
$this->context->controller->errors[] = $this->l('Zakeke failed to initialize');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add the Zakeke elements inside the product page of customizable products
|
|
*
|
|
* @param array $params
|
|
*/
|
|
public function hookDisplayMobileHeader($params)
|
|
{
|
|
if (_PS_VERSION_ < 1.7) {
|
|
$this->hookDisplayHeaderPS16();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add the Zakeke elements inside the product page of customizable products
|
|
*
|
|
* @param array $params
|
|
*/
|
|
public function hookDisplayHeader($params)
|
|
{
|
|
if (_PS_VERSION_ < 1.7) {
|
|
$this->hookDisplayHeaderPS16();
|
|
} else {
|
|
$this->hookDisplayHeaderPS17();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* dd the Zakeke elements inside the Prestashop's admin
|
|
*
|
|
* @param array $params
|
|
*/
|
|
public function hookActionAdminControllerSetMedia($params)
|
|
{
|
|
if (_PS_VERSION_ < 1.7) {
|
|
$zakekeAdminInfo = $this->context->link->getAdminLink('AdminZakeke');
|
|
Media::addJsDef(array(
|
|
'zakekeAdminInfo' => addcslashes($zakekeAdminInfo, "'")
|
|
));
|
|
$this->context->controller->addJS($this->_path . 'views/js/ps16/admin_update.js');
|
|
} else {
|
|
$this->context->controller->addJS($this->_path . 'views/js/admin_update.js');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Correctly display the Zakeke customization both on FO and BO
|
|
*
|
|
* @param array $params
|
|
*
|
|
* @return string
|
|
*/
|
|
public function hookDisplayCustomization($params)
|
|
{
|
|
try {
|
|
$customization = $params['customization'];
|
|
$zakekeData = json_decode($customization['value'], true);
|
|
|
|
$zakekeDisplayCustomization = new ZakekeDisplayCustomization($this->getZakekeApi(), $this->context);
|
|
$templatesVariables = $zakekeDisplayCustomization->getTemplatesVariables($zakekeData);
|
|
$this->context->smarty->assign($templatesVariables);
|
|
|
|
if (!$this->order_resend_is_executing
|
|
&& isset($templatesVariables['zakeke_download_show'])
|
|
&& $templatesVariables['zakeke_download_show']
|
|
&& isset($templatesVariables['zakeke_download_ready'])
|
|
&& !$templatesVariables['zakeke_download_ready']) {
|
|
$id_order = Tools::getValue('id_order');
|
|
if ($id_order) {
|
|
$this->order_resend_is_executing = true;
|
|
$order = new Order(Tools::getValue('id_order'));
|
|
if (Validate::isLoadedObject($order) && ($order->hasBeenPaid() || $order->isInPreparation())) {
|
|
$zakekeOrderService = new ZakekeOrderService($this);
|
|
$zakekeOrderService->process($order);
|
|
$this->order_resend_is_executing = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this->display(__FILE__, 'displayCustomization.tpl');
|
|
} catch (Exception $e) {
|
|
PrestaShopLogger::addLog('Zakeke hookDisplayCustomization Call error: ' . $e);
|
|
$this->context->controller->errors[] = $this->l('Zakeke failed to get the customization details');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Correctly display the Zakeke customization both on FO and BO
|
|
*
|
|
* @param array $params
|
|
*
|
|
* @return string
|
|
*/
|
|
public function hookDisplayCartExtraProductActions($params)
|
|
{
|
|
try {
|
|
$product = $params['product'];
|
|
|
|
if (!isset($product['id_customization'])) {
|
|
return '';
|
|
}
|
|
|
|
$id_customization = $product['id_customization'];
|
|
$customization_data = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(
|
|
'SELECT `value` FROM `' . _DB_PREFIX_ . 'customized_data`
|
|
WHERE `id_customization` = ' . (int)($id_customization)
|
|
);
|
|
if (!$customization_data) {
|
|
return '';
|
|
}
|
|
|
|
$zakekeEditUrl = new ZakekeEditUrl($product, $customization_data, $this->context);
|
|
$edit_url = $zakekeEditUrl->getEditUrl();
|
|
|
|
if ($edit_url === false) {
|
|
return '';
|
|
}
|
|
|
|
$this->context->smarty->assign('zakeke_edit_url', $edit_url);
|
|
return $this->display(__FILE__, 'displayCartExtraProductActions.tpl');
|
|
} catch (Exception $e) {
|
|
PrestaShopLogger::addLog('Zakeke hookDisplayCartExtraProductActions Call error: ' . $e);
|
|
$this->context->controller->errors[] = $this->l('Zakeke failed to get the edit link');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register orders that contains Zakeke products
|
|
*
|
|
* @param array $params
|
|
*/
|
|
public function hookDisplayOrderConfirmation($params)
|
|
{
|
|
try {
|
|
/** @var Order $order */
|
|
$order = null;
|
|
|
|
if (_PS_VERSION_ < 1.7) {
|
|
$order = $params['objOrder'];
|
|
} else {
|
|
$order = $params['order'];
|
|
}
|
|
|
|
$zakekeOrderService = new ZakekeOrderService($this);
|
|
if ($order !== null && method_exists($order, 'getProducts')) {
|
|
$zakekeOrderService->process($order);
|
|
}
|
|
} catch (Exception $e) {
|
|
PrestaShopLogger::addLog('Zakeke hookDisplayOrderConfirmation Call error: ' . $e);
|
|
$this->context->controller->errors[] = $this->l('Zakeke failed to register the order');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register the Admin controller for Zakeke
|
|
*
|
|
* @return bool
|
|
* @throws PrestaShopDatabaseException
|
|
* @throws PrestaShopException
|
|
*/
|
|
public function createAjaxController()
|
|
{
|
|
$tab = new Tab();
|
|
$tab->active = 1;
|
|
$languages = Language::getLanguages(false);
|
|
if (is_array($languages)) {
|
|
foreach ($languages as $language) {
|
|
$tab->name[$language['id_lang']] = 'zakeke';
|
|
}
|
|
}
|
|
$tab->class_name = 'AdminZakeke';
|
|
$tab->module = $this->name;
|
|
$tab->id_parent = -1;
|
|
return (bool)$tab->add();
|
|
}
|
|
|
|
/**
|
|
* Associate a Zakeke guest to the store customer
|
|
*
|
|
* @param $params
|
|
*/
|
|
public function hookActionAuthentication($params)
|
|
{
|
|
try {
|
|
/** @var Customer $customer */
|
|
$customer = $params['customer'];
|
|
|
|
$zakekeGuestCode = $this->getZakekeGuestCode(false);
|
|
|
|
if (!$zakekeGuestCode) {
|
|
return;
|
|
}
|
|
|
|
$this->getZakekeApi()->associateGuest($zakekeGuestCode, $customer->id);
|
|
} catch (Exception $e) {
|
|
PrestaShopLogger::addLog('Zakeke hookActionAuthentication Call error: ' . $e);
|
|
$this->context->controller->errors[] = $this->l('Zakeke failed to associate the guest user');
|
|
}
|
|
}
|
|
|
|
public function hookActionCartSave()
|
|
{
|
|
if ($this->cart_action_is_executing) {
|
|
return;
|
|
}
|
|
|
|
$this->cart_action_is_executing = true;
|
|
ZakekePrice::updateCartZakekePrice($this->context, $this);
|
|
$this->cart_action_is_executing = false;
|
|
}
|
|
|
|
public function hookActionObjectProductInCartDeleteBefore($data)
|
|
{
|
|
if ($this->cart_action_is_executing) {
|
|
return;
|
|
}
|
|
|
|
$this->cart_action_is_executing = true;
|
|
ZakekePrice::updateCartZakekePrice($this->context, $this);
|
|
$this->cart_action_is_executing = false;
|
|
}
|
|
|
|
public function installDB()
|
|
{
|
|
$return = true;
|
|
$return &= Db::getInstance()->execute('
|
|
CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'zakeke_enabled` (
|
|
`id_zakeke_enabled` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
`id_product` int(11) NOT NULL,
|
|
PRIMARY KEY (`id_zakeke_enabled`),
|
|
UNIQUE KEY `id_product` (`id_product`)
|
|
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8 ;');
|
|
|
|
$return &= Db::getInstance()->execute('
|
|
CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'zakeke_item` (
|
|
`id_zakeke_item` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
`id_item` varchar(254) NOT NULL,
|
|
`preview` varchar(254) NOT NULL,
|
|
`pricing_json` varchar(254) NOT NULL,
|
|
PRIMARY KEY (`id_zakeke_item`),
|
|
UNIQUE KEY `id_item` (`id_item`)
|
|
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8 ;');
|
|
|
|
$return &= Db::getInstance()->execute('
|
|
CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'zakeke_configurator_enabled` (
|
|
`id_zakeke_configurator_enabled` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
`id_product` int(11) NOT NULL,
|
|
PRIMARY KEY (`id_zakeke_configurator_enabled`),
|
|
UNIQUE KEY `id_product` (`id_product`)
|
|
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8 ;');
|
|
|
|
$return &= Db::getInstance()->execute('
|
|
CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'zakeke_configurator_item` (
|
|
`id_zakeke_configurator_item` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
`id_configurator_item` varchar(254) NOT NULL,
|
|
`preview` varchar(254) NOT NULL,
|
|
`price` DECIMAL(20,6) NOT NULL,
|
|
`items_json` varchar(6000) NOT NULL,
|
|
PRIMARY KEY (`id_zakeke_configurator_item`),
|
|
UNIQUE KEY `id_item` (`id_configurator_item`)
|
|
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8 ;');
|
|
|
|
return $return;
|
|
}
|
|
|
|
private function registerHooks()
|
|
{
|
|
$result = $this->registerHook('displayHeader')
|
|
&& $this->registerHook('displayOrderConfirmation')
|
|
&& $this->registerHook('actionCartSave')
|
|
&& $this->registerHook('actionAdminControllerSetMedia');
|
|
|
|
if (_PS_VERSION_ < 1.7) {
|
|
return $result
|
|
&& $this->registerHook('displayMobileHeader')
|
|
&& $this->createAjaxController();
|
|
}
|
|
|
|
return $result
|
|
&& $this->registerHook('addWebserviceResources')
|
|
&& $this->registerHook('displayCustomization')
|
|
&& $this->registerHook('displayCartExtraProductActions');
|
|
}
|
|
|
|
public function install()
|
|
{
|
|
if (Shop::isFeatureActive()) {
|
|
Shop::setContext(Shop::CONTEXT_ALL);
|
|
}
|
|
|
|
return parent::install() &&
|
|
$this->installDB() &&
|
|
$this->registerHooks();
|
|
}
|
|
|
|
public function uninstall()
|
|
{
|
|
Configuration::deleteByName('ZAKEKE_FORCE');
|
|
|
|
$id_tab = (int)Tab::getIdFromClassName('AdminZakeke');
|
|
if ($id_tab) {
|
|
$tab = new Tab($id_tab);
|
|
$tab->delete();
|
|
}
|
|
|
|
return parent::uninstall();
|
|
}
|
|
}
|