From acded73829866a596b107cbae79b1805ec751780 Mon Sep 17 00:00:00 2001
From: David Molina Cano <128705267+davidmolinacano@users.noreply.github.com>
Date: Mon, 7 Oct 2024 08:31:04 +0200
Subject: [PATCH 1/2] PLUGINRANGERS-234 | Master file refactor step 1:
Separated install process + autoloader (#240)
* feat: Separated install process + autoloader. First approach
* fix: Fixed several files
* feat: use Db; in upgrade 4.5.0
* fix: Fixes after testing everything carefully
* feat: Renamed buildFeedUrl to getFeedUrl
* feat: Changes to pass the Prestashop validator at 100%
---
autoloader.php | 56 +++
doofinder-ajax.php | 7 +-
doofinder.php | 457 ++----------------
lib/DoofinderConfig.php | 66 +++
lib/DoofinderConstants.php | 32 ++
lib/EasyREST.php | 3 +
lib/SearchEngine.php | 50 ++
lib/UrlManager.php | 82 ++++
lib/doofinder_api_index.php | 2 +-
lib/doofinder_api_items.php | 7 +-
lib/doofinder_api_landing.php | 6 +-
lib/doofinder_api_unique_script.php | 6 +-
lib/doofinder_installation.php | 273 ++++++++++-
lib/doofinder_layer_api.php | 2 +-
views/js/doofinder-onboarding.js | 2 +-
views/templates/admin/indexation_status.tpl | 4 +-
views/templates/admin/onboarding_tab.tpl | 4 +-
.../front/catalog/_partials/productlist.tpl | 2 +-
18 files changed, 627 insertions(+), 434 deletions(-)
create mode 100644 autoloader.php
create mode 100644 lib/DoofinderConfig.php
create mode 100644 lib/DoofinderConstants.php
create mode 100644 lib/SearchEngine.php
create mode 100644 lib/UrlManager.php
diff --git a/autoloader.php b/autoloader.php
new file mode 100644
index 0000000..12902d3
--- /dev/null
+++ b/autoloader.php
@@ -0,0 +1,56 @@
+autoinstaller($shop_id);
+ DoofinderInstallation::autoinstaller($shop_id);
echo json_encode(['success' => true]);
exit;
} else {
diff --git a/doofinder.php b/doofinder.php
index 329b51c..7f3aecc 100644
--- a/doofinder.php
+++ b/doofinder.php
@@ -1,5 +1,4 @@
confirmUninstall = $this->l('Are you sure? This will not cancel your account in Doofinder service');
$this->admin_template_dir = '../../../../modules/' . $this->name . '/views/templates/admin/';
-
- $olderPS17 = (version_compare(_PS_VERSION_, '1.7', '<') === true);
}
/**
@@ -65,8 +73,8 @@ public function __construct()
public function install()
{
return parent::install()
- && $this->installDb()
- && $this->installTabs()
+ && DoofinderInstallation::installDb()
+ && DoofinderInstallation::installTabs()
&& $this->registerHook('displayHeader')
&& $this->registerHook('moduleRoutes')
&& $this->registerHook('actionProductSave')
@@ -79,38 +87,6 @@ public function install()
&& $this->registerHook('actionObjectCategoryDeleteAfter');
}
- /**
- * Install the module database tables
- *
- * @return bool
- */
- public function installDb()
- {
- return Db::getInstance()->execute(
- '
- CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'doofinder_updates` (
- `id_doofinder_update` INT UNSIGNED NOT NULL AUTO_INCREMENT,
- `id_shop` INT(10) UNSIGNED NOT NULL,
- `object` varchar(45) NOT NULL,
- `id_object` INT(10) UNSIGNED NOT NULL,
- `action` VARCHAR(45) NOT NULL,
- `date_upd` DATETIME NOT NULL,
- PRIMARY KEY (`id_doofinder_update`),
- CONSTRAINT uc_shop_update UNIQUE KEY (id_shop,object,id_object)
- ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8 ;'
- )
- && Db::getInstance()->execute(
- '
- CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'doofinder_landing` (
- `name` VARCHAR(45) NOT NULL,
- `hashid` VARCHAR(45) NOT NULL,
- `data` TEXT NOT NULL,
- `date_upd` DATETIME NOT NULL,
- PRIMARY KEY (`name`, `hashid`)
- ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8 ;'
- );
- }
-
/**
* Uninstall the module and its dependencies
*
@@ -119,85 +95,9 @@ public function installDb()
public function uninstall()
{
return parent::uninstall()
- && $this->uninstallTabs()
- && $this->deleteConfigVars()
- && $this->uninstallDb();
- }
-
- /**
- * Remove module-dependent configuration variables
- *
- * @return bool
- */
- public function deleteConfigVars()
- {
- $config_vars = [
- 'DF_AI_ADMIN_ENDPOINT',
- 'DF_AI_API_ENDPOINT',
- 'DF_AI_APIKEY',
- 'DF_API_KEY',
- 'DF_API_LAYER_DESCRIPTION',
- 'DF_CSS_VS',
- 'DF_CUSTOMEXPLODEATTR',
- 'DF_DEBUG',
- 'DF_DEBUG_CURL',
- 'DF_DSBL_AJAX_TKN',
- 'DF_DSBL_DFCKIE_JS',
- 'DF_DSBL_DFFAC_JS',
- 'DF_DSBL_DFLINK_JS',
- 'DF_DSBL_DFPAG_JS',
- 'DF_DSBL_FAC_CACHE',
- 'DF_DSBL_HTTPS_CURL',
- 'DF_EB_LAYER_DESCRIPTION',
- 'DF_ENABLED_V9',
- 'DF_ENABLE_HASH',
- 'DF_EXTRA_CSS',
- 'DF_FACETS_TOKEN',
- 'DF_FEATURES_SHOWN',
- 'DF_FEED_FULL_PATH',
- 'DF_FEED_INDEXED',
- 'DF_FEED_MAINCATEGORY_PATH',
- 'DF_GROUP_ATTRIBUTES_SHOWN',
- 'DF_GS_DESCRIPTION_TYPE',
- 'DF_GS_DISPLAY_PRICES',
- 'DF_GS_IMAGE_SIZE',
- 'DF_GS_PRICES_USE_TAX',
- 'DF_INSTALLATION_ID',
- 'DF_SHOW_LAYER',
- 'DF_SHOW_LAYER_MOBILE',
- 'DF_REGION',
- 'DF_RESTART_OV',
- 'DF_SHOW_PRODUCT_FEATURES',
- 'DF_SHOW_PRODUCT_VARIATIONS',
- 'DF_UPDATE_ON_SAVE_DELAY',
- 'DF_UPDATE_ON_SAVE_LAST_EXEC',
- 'DF_FEED_INDEXED',
- ];
-
- $hashid_vars = array_column(
- Db::getInstance()->executeS('
- SELECT name FROM ' . _DB_PREFIX_ . "configuration where name like 'DF_HASHID_%'"),
- 'name'
- );
-
- $config_vars = array_merge($config_vars, $hashid_vars);
-
- foreach ($config_vars as $var) {
- Configuration::deleteByName($var);
- }
-
- return true;
- }
-
- /**
- * Removes the database tables from the module
- *
- * @return bool
- */
- public function uninstallDb()
- {
- return Db::getInstance()->execute('DROP TABLE `' . _DB_PREFIX_ . 'doofinder_updates`')
- && Db::getInstance()->execute('DROP TABLE `' . _DB_PREFIX_ . 'doofinder_landing`');
+ && DoofinderInstallation::uninstallTabs()
+ && DoofinderInstallation::deleteConfigVars()
+ && DoofinderInstallation::uninstallDb();
}
/**
@@ -223,6 +123,17 @@ public function hookModuleRoutes()
];
}
+ /**
+ * Update the hashid of the search engines of the store in the configuration.
+ * It must be declared here too to be used by upgrade 4.5.0.
+ *
+ * @return true
+ */
+ public function setSearchEnginesByConfig()
+ {
+ return SearchEngine::setSearchEnginesByConfig();
+ }
+
/**
* Handles the module's configuration page
*
@@ -324,26 +235,6 @@ protected function isConfigured()
return Db::getInstance()->getValue($sql);
}
- /**
- * Build feed urls
- *
- * @param int $shop_id
- * @param int $language
- * @param int $currency
- *
- * @return string
- */
- protected function buildFeedUrl($shop_id, $language, $currency)
- {
- $shop_url = $this->getShopURL($shop_id);
-
- return $shop_url . ltrim('modules/' . $this->name, DIRECTORY_SEPARATOR)
- . '/feed.php?'
- . 'currency=' . Tools::strtoupper($currency)
- . '&language=' . Tools::strtoupper($language)
- . '&dfsec_hash=' . Configuration::get('DF_API_KEY');
- }
-
/**
* Check if the form to create a store installation has to be displayed
*
@@ -661,7 +552,7 @@ protected function renderFeedURLs()
$currencyIso = Tools::strtoupper($cur['iso_code']);
$langIso = Tools::strtoupper($lang['iso_code']);
$urls[] = [
- 'url' => $this->buildFeedUrl($this->context->shop->id, $langIso, $currencyIso),
+ 'url' => UrlManager::getFeedUrl($this->context->shop->id, $langIso, $currencyIso),
'lang' => $langIso,
'currency' => $currencyIso,
];
@@ -801,7 +692,7 @@ protected function postProcess()
if ($formUpdated == 'data_feed_tab') {
if ((bool) Configuration::get('DF_UPDATE_ON_SAVE_DELAY')) {
- $this->setSearchEnginesByConfig();
+ SearchEngine::setSearchEnginesByConfig();
}
if (Tools::getValue('DF_UPDATE_ON_SAVE_DELAY') && (int) Tools::getValue('DF_UPDATE_ON_SAVE_DELAY') < 5) {
Configuration::updateValue('DF_UPDATE_ON_SAVE_DELAY', 5);
@@ -1255,7 +1146,7 @@ private function updateItemsApi($hashid, $type, $payload)
$response = $api->updateBulk($payload);
if (isset($response['error']) && !empty($response['error'])) {
- $this->debug(json_encode($response['error']));
+ DoofinderConfig::debug(json_encode($response['error']));
}
}
@@ -1274,7 +1165,7 @@ private function deleteItemsApi($hashid, $type, $payload)
$response = $api->deleteBulk(json_encode($payload));
if (isset($response['error']) && !empty($response['error'])) {
- $this->debug(json_encode($response['error']));
+ DoofinderConfig::debug(json_encode($response['error']));
}
}
@@ -1285,9 +1176,9 @@ private function indexApiInvokeReindexing()
$region = Configuration::get('DF_REGION');
$api_key = Configuration::get('DF_API_KEY');
$api = new DoofinderApiIndex($api_key, $region);
- $response = $api->invokeReindexing(Configuration::get('DF_INSTALLATION_ID'), $this->getProcessCallbackUrl());
+ $response = $api->invokeReindexing(Configuration::get('DF_INSTALLATION_ID'), UrlManager::getProcessCallbackUrl());
if (empty($response) || $response['status'] !== 200) {
- $this->debug('Error while invoking reindexing: ' . json_encode($response));
+ DoofinderConfig::debug('Error while invoking reindexing: ' . json_encode($response));
return;
}
@@ -1297,15 +1188,13 @@ private function indexApiInvokeReindexing()
private function is_valid_update_on_save()
{
- require_once 'lib/doofinder_installation.php';
-
$region = Configuration::get('DF_REGION');
$api_key = Configuration::get('DF_API_KEY');
$api = new DoofinderInstallation($api_key, $region);
- $decode_response = $api->is_valid_update_on_save(Configuration::get('DF_INSTALLATION_ID'));
+ $decode_response = $api->isValidUpdateOnSave(Configuration::get('DF_INSTALLATION_ID'));
if (empty($decode_response)) {
- $this->debug('Error checking search engines: ' . json_encode($decode_response));
+ DoofinderConfig::debug('Error checking search engines: ' . json_encode($decode_response));
Configuration::updateValue('DF_UPDATE_ON_SAVE_DELAY', 0);
@@ -1395,10 +1284,7 @@ public function searchOnApi($string, $page = 1, $page_size = 12, $timeout = 8000
$page = 1;
}
$query_name = Tools::getValue('df_query_name', false);
- $debug = Configuration::get('DF_DEBUG');
- if (isset($debug) && $debug) {
- $this->debug('Search On API Start');
- }
+ DoofinderConfig::debug('Search On API Start');
$hash_id = $this->getHashId(Context::getContext()->language->id, Context::getContext()->currency->id);
$api_key = Configuration::get('DF_API_KEY');
$show_variations = Configuration::get('DF_SHOW_PRODUCT_VARIATIONS');
@@ -1464,9 +1350,7 @@ public function searchOnApi($string, $page = 1, $page_size = 12, $timeout = 8000
$product_pool = '0';
}
- if (isset($debug) && $debug) {
- $this->debug("Product Pool: $product_pool");
- }
+ DoofinderConfig::debug("Product Pool: $product_pool");
$product_pool_attributes = implode(',', $product_pool_attributes);
@@ -1476,9 +1360,7 @@ public function searchOnApi($string, $page = 1, $page_size = 12, $timeout = 8000
$product_pool_attributes = '0';
}
- if (isset($debug) && $debug) {
- $this->debug("Product Pool Attributes: $product_pool_attributes");
- }
+ DoofinderConfig::debug("Product Pool Attributes: $product_pool_attributes");
$db = Db::getInstance(_PS_USE_SQL_SLAVE_);
$id_lang = $context->language->id;
$sql = 'SELECT p.*, product_shop.*, stock.out_of_stock,
@@ -1554,9 +1436,8 @@ public function searchOnApi($string, $page = 1, $page_size = 12, $timeout = 8000
' ORDER BY FIELD (p.`id_product`,' . pSQL($product_pool) . ') '
. (($show_variations) ? ' , FIELD (product_attribute_shop.`id_product_attribute`,'
. pSQL($product_pool_attributes) . ')' : '');
- if (isset($debug) && $debug) {
- $this->debug("SQL: $sql");
- }
+
+ DoofinderConfig::debug("SQL: $sql");
$result = $db->executeS($sql);
@@ -1599,29 +1480,6 @@ public function searchOnApi($string, $page = 1, $page_size = 12, $timeout = 8000
}
}
- /**
- * Update the hashid of the search engines of the store in the configuration
- *
- * @return true
- */
- public function setSearchEnginesByConfig()
- {
- require_once _PS_MODULE_DIR_ . 'doofinder/lib/doofinder_layer_api.php';
- $installationID = Configuration::get('DF_INSTALLATION_ID');
- $api_key = Configuration::get('DF_API_KEY');
- $region = Configuration::get('DF_REGION');
-
- $data = DoofinderLayerApi::getInstallationData($installationID, $api_key, $region);
-
- foreach ($data['config']['search_engines'] as $lang => $currencies) {
- foreach ($currencies as $currency => $hashid) {
- Configuration::updateValue('DF_HASHID_' . strtoupper($currency) . '_' . strtoupper($lang), $hashid);
- }
- }
-
- return true;
- }
-
/**
* Checks the connection with DooManager
*
@@ -1629,10 +1487,8 @@ public function setSearchEnginesByConfig()
*/
public function checkOutsideConnection()
{
- // Require only on this function to not overload memory with not needed classes
- require_once _PS_MODULE_DIR_ . 'doofinder/lib/EasyREST.php';
$client = new EasyREST(true, 3);
- $result = $client->get(sprintf('%s/auth/login', self::DOOMANAGER_URL));
+ $result = $client->get(sprintf('%s/auth/login', DoofinderConstants::DOOMANAGER_URL));
return $result && $result->originalResponse && isset($result->headers['code'])
&& (strpos($result->originalResponse, 'HTTP/2 200') || $result->headers['code'] == 200);
@@ -1664,175 +1520,6 @@ public function saveApiData($apikey, $api_endpoint, $admin_endpoint)
}
}
- /**
- * Start the installation process
- * If shop_id is null, install all shops
- *
- * @param int $shop_id
- *
- * @return void
- */
- public function autoinstaller($shop_id = null)
- {
- if (!empty($shop_id)) {
- $shop = Shop::getShop($shop_id);
- $this->createStore($shop);
-
- return;
- }
-
- $shops = Shop::getShops();
- foreach ($shops as $shop) {
- $this->createStore($shop);
- }
- }
-
- /**
- * Create a store in Doofinder based on the Prestashop shop
- *
- * @param array $shop
- *
- * @return void
- */
- public function createStore($shop)
- {
- // Require only on this function to not overload memory with unneeded classes
- require_once _PS_MODULE_DIR_ . 'doofinder/lib/EasyREST.php';
- $client = new EasyREST();
- $apikey = Configuration::getGlobalValue('DF_AI_APIKEY');
- $languages = Language::getLanguages(true, $shop['id_shop']);
- $currencies = Currency::getCurrenciesByIdShop($shop['id_shop']);
- $shopId = $shop['id_shop'];
- $shopGroupId = $shop['id_shop_group'];
- $primary_lang = new Language(Configuration::get('PS_LANG_DEFAULT', null, $shopGroupId, $shopId));
- $installationID = null;
-
- $this->setDefaultShopConfig($shopGroupId, $shopId);
-
- $shop_url = $this->getShopURL($shopId);
- $store_data = [
- 'name' => $shop['name'],
- 'platform' => 'prestashop',
- 'primary_language' => $primary_lang->language_code,
- 'site_url' => $shop_url,
- 'search_engines' => [],
- 'plugin_version' => $this->version,
- ];
-
- foreach ($languages as $lang) {
- if ($lang['active'] == 0) {
- continue;
- }
- foreach ($currencies as $cur) {
- if ($cur['deleted'] == 1 || $cur['active'] == 0) {
- continue;
- }
- $ciso = $cur['iso_code'];
- $lang_code = $lang['language_code'];
- $feed_url = $this->buildFeedUrl($shopId, $lang['iso_code'], $ciso);
- $store_data['search_engines'][] = [
- 'language' => $lang_code,
- 'currency' => $ciso,
- 'feed_url' => $feed_url,
- 'callback_url' => $this->getProcessCallbackUrl(),
- ];
- }
- }
-
- $json_store_data = json_encode($store_data);
- $this->debug('Create Store Start');
- $this->debug(print_r($store_data, true));
-
- $response = $client->post(
- $this->getInstallUrl(Configuration::get('DF_REGION')),
- $json_store_data,
- false,
- false,
- 'application/json',
- ['Authorization: Token ' . $apikey]
- );
-
- if ($response->getResponseCode() == 200) {
- $response = json_decode($response->response, true);
- $installationID = @$response['installation_id'];
- $this->debug('Create Store response:');
- $this->debug(print_r($response, true));
-
- if ($installationID) {
- $this->debug("Set installation ID: $installationID");
- Configuration::updateValue('DF_INSTALLATION_ID', $installationID, false, $shopGroupId, $shopId);
- Configuration::updateValue('DF_ENABLED_V9', true, false, $shopGroupId, $shopId);
- Configuration::updateValue('DF_SHOW_LAYER', true, false, $shopGroupId, $shopId);
- Configuration::updateValue('DF_SHOW_LAYER_MOBILE', true, false, $shopGroupId, $shopId);
- $this->setSearchEnginesByConfig();
- } else {
- $this->debug('Invalid installation ID');
- exit('ko');
- }
- } else {
- $error_msg = "Create Store failed with code {$response->getResponseCode()} and message '{$response->getResponseMessage()}'";
- $response_msg = 'Response: ' . print_r($response->response, true);
- $this->debug($error_msg);
- $this->debug($response_msg);
- echo $response->response;
- exit;
- }
- }
-
- /**
- * Get Process Callback URL
- *
- * @return string
- */
- private function getProcessCallbackUrl()
- {
- return Context::getContext()->link->getModuleLink('doofinder', 'callback', []);
- }
-
- /**
- * Set the default values in the configuration
- *
- * @param int $shopGroupId
- * @param int $shopId
- *
- * @return void
- */
- public function setDefaultShopConfig($shopGroupId, $shopId)
- {
- $apikey = Configuration::getGlobalValue('DF_AI_APIKEY');
- $api_endpoint = Configuration::getGlobalValue('DF_AI_API_ENDPOINT');
- $api_endpoint_array = explode('-', $api_endpoint);
- $region = $api_endpoint_array[0];
-
- Configuration::updateValue('DF_ENABLE_HASH', true, false, $shopGroupId, $shopId);
- Configuration::updateValue('DF_GS_DISPLAY_PRICES', true, false, $shopGroupId, $shopId);
- Configuration::updateValue('DF_GS_PRICES_USE_TAX', true, false, $shopGroupId, $shopId);
- Configuration::updateValue('DF_FEED_FULL_PATH', true, false, $shopGroupId, $shopId);
- Configuration::updateValue('DF_SHOW_PRODUCT_VARIATIONS', 0, false, $shopGroupId, $shopId);
- Configuration::updateValue('DF_REGION', $region, false, $shopGroupId, $shopId);
- Configuration::updateValue('DF_API_KEY', $region . '-' . $apikey, false, $shopGroupId, $shopId);
- Configuration::updateValue('DF_GS_DESCRIPTION_TYPE', self::GS_SHORT_DESCRIPTION, false, $shopGroupId, $shopId);
- Configuration::updateValue('DF_FEED_MAINCATEGORY_PATH', false, false, $shopGroupId, $shopId);
- Configuration::updateValue('DF_GS_IMAGE_SIZE', key(dfTools::getAvailableImageSizes()), false, $shopGroupId, $shopId);
- }
-
- /**
- * Get store URL
- *
- * @param int $shop_id
- *
- * @return string
- */
- public function getShopURL($shop_id)
- {
- $shop = new Shop($shop_id);
- $force_ssl = (Configuration::get('PS_SSL_ENABLED')
- && Configuration::get('PS_SSL_ENABLED_EVERYWHERE'));
- $url = ($force_ssl) ? 'https://' . $shop->domain_ssl : 'http://' . $shop->domain;
-
- return $url . $this->getShopBaseURI($shop);
- }
-
/**
* Check the connection to the API using the saved API KEY
*
@@ -1978,22 +1665,6 @@ private function getWarningMultishopHtml()
return $stop;
}
- private function getShopBaseURI($shop)
- {
- return $shop->physical_uri . $shop->virtual_uri;
- }
-
- private function debug($message)
- {
- $current_path = dirname($_SERVER['SCRIPT_FILENAME']);
- if (!is_dir($current_path)) {
- $current_path = dirname(__FILE__);
- }
- if (isset($debug) && $debug) {
- error_log("$message\n", 3, $current_path . '/doofinder.log');
- }
- }
-
private function displayErrorCtm($error, $link = false, $raw = false)
{
return $this->displayGeneralMsg($error, 'error', 'danger', $link, $raw);
@@ -2035,36 +1706,4 @@ private function searchLayerMustBeInitialized()
return ($isMobile && $displayMobile) || (!$isMobile && $displayDesktop);
}
-
- private function installTabs()
- {
- $tab = new Tab();
- $tab->active = 0;
- $tab->class_name = 'DoofinderAdmin';
- $tab->name = [];
- foreach (Language::getLanguages() as $lang) {
- $tab->name[$lang['id_lang']] = 'Doofinder admin controller';
- }
- $tab->id_parent = 0;
- $tab->module = $this->name;
-
- return $tab->save();
- }
-
- private function uninstallTabs()
- {
- $tabId = (int) Tab::getIdFromClassName('DoofinderAdmin');
- if (!$tabId) {
- return true;
- }
-
- $tab = new Tab($tabId);
-
- return $tab->delete();
- }
-
- private function getInstallUrl($region)
- {
- return str_replace('{region}', $region, 'https://{region}-plugins.doofinder.com/install');
- }
}
diff --git a/lib/DoofinderConfig.php b/lib/DoofinderConfig.php
new file mode 100644
index 0000000..3c6d07f
--- /dev/null
+++ b/lib/DoofinderConfig.php
@@ -0,0 +1,66 @@
+ $currencies) {
+ foreach ($currencies as $currency => $hashid) {
+ \Configuration::updateValue('DF_HASHID_' . strtoupper($currency) . '_' . strtoupper($lang), $hashid);
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/lib/UrlManager.php b/lib/UrlManager.php
new file mode 100644
index 0000000..c150938
--- /dev/null
+++ b/lib/UrlManager.php
@@ -0,0 +1,82 @@
+domain_ssl : 'http://' . $shop->domain;
+
+ return $url . self::_getShopBaseURI($shop);
+ }
+
+ /**
+ * Build feed urls
+ *
+ * @param int $shopId
+ * @param int $language
+ * @param int $currency
+ *
+ * @return string
+ */
+ public static function getFeedUrl($shopId, $language, $currency)
+ {
+ $shopUrl = self::getShopURL($shopId);
+
+ return $shopUrl . ltrim('modules/' . DoofinderConstants::NAME, DIRECTORY_SEPARATOR)
+ . '/feed.php?'
+ . 'currency=' . \Tools::strtoupper($currency)
+ . '&language=' . \Tools::strtoupper($language)
+ . '&dfsec_hash=' . \Configuration::get('DF_API_KEY');
+ }
+
+ /**
+ * Get Process Callback URL
+ *
+ * @return string
+ */
+ public static function getProcessCallbackUrl()
+ {
+ return \Context::getContext()->link->getModuleLink('doofinder', 'callback', []);
+ }
+
+ public static function getInstallUrl($region)
+ {
+ return str_replace('{region}', $region, 'https://{region}-plugins.doofinder.com/install');
+ }
+
+ private static function _getShopBaseURI($shop)
+ {
+ return $shop->physical_uri . $shop->virtual_uri;
+ }
+}
diff --git a/lib/doofinder_api_index.php b/lib/doofinder_api_index.php
index 7a1c93f..80430f6 100644
--- a/lib/doofinder_api_index.php
+++ b/lib/doofinder_api_index.php
@@ -12,7 +12,7 @@
* @copyright Doofinder
* @license GPLv3
*/
-require_once _PS_MODULE_DIR_ . 'doofinder/lib/EasyREST.php';
+use PrestaShop\Module\Doofinder\Lib\EasyREST;
if (!defined('_PS_VERSION_')) {
exit;
diff --git a/lib/doofinder_api_items.php b/lib/doofinder_api_items.php
index 3c4a30f..08ecb48 100644
--- a/lib/doofinder_api_items.php
+++ b/lib/doofinder_api_items.php
@@ -12,7 +12,7 @@
* @copyright Doofinder
* @license GPLv3
*/
-require_once _PS_MODULE_DIR_ . 'doofinder/lib/EasyREST.php';
+use PrestaShop\Module\Doofinder\Lib\EasyREST;
if (!defined('_PS_VERSION_')) {
exit;
@@ -22,6 +22,11 @@
class DoofinderApiItems
{
+ private $hashid;
+ private $api_key;
+ private $api_url;
+ private $type;
+
public function __construct($hashid, $api_key, $region, $type = 'product')
{
$this->hashid = $hashid;
diff --git a/lib/doofinder_api_landing.php b/lib/doofinder_api_landing.php
index 15a2648..18f486c 100644
--- a/lib/doofinder_api_landing.php
+++ b/lib/doofinder_api_landing.php
@@ -12,7 +12,7 @@
* @copyright Doofinder
* @license GPLv3
*/
-require_once _PS_MODULE_DIR_ . 'doofinder/lib/EasyREST.php';
+use PrestaShop\Module\Doofinder\Lib\EasyREST;
if (!defined('_PS_VERSION_')) {
exit;
@@ -22,6 +22,10 @@
class DoofinderApiLanding
{
+ private $hashid;
+ private $api_key;
+ private $api_url;
+
public function __construct($hashid, $api_key, $region)
{
$this->hashid = $hashid;
diff --git a/lib/doofinder_api_unique_script.php b/lib/doofinder_api_unique_script.php
index 7a75581..57a5df8 100644
--- a/lib/doofinder_api_unique_script.php
+++ b/lib/doofinder_api_unique_script.php
@@ -12,7 +12,7 @@
* @copyright Doofinder
* @license GPLv3
*/
-require_once _PS_MODULE_DIR_ . 'doofinder/lib/EasyREST.php';
+use PrestaShop\Module\Doofinder\Lib\EasyREST;
if (!defined('_PS_VERSION_')) {
exit;
@@ -22,6 +22,10 @@
class DoofinderApiUniqueScript
{
+ private $installationId;
+ private $apiKey;
+ private $apiUrl;
+
public function __construct($installationId, $region, $apiKey)
{
$this->installationId = $installationId;
diff --git a/lib/doofinder_installation.php b/lib/doofinder_installation.php
index 0dbaead..3edcbe4 100644
--- a/lib/doofinder_installation.php
+++ b/lib/doofinder_installation.php
@@ -12,23 +12,22 @@
* @copyright Doofinder
* @license GPLv3
*/
-require_once _PS_MODULE_DIR_ . 'doofinder/lib/EasyREST.php';
+
+namespace PrestaShop\Module\Doofinder\Lib;
if (!defined('_PS_VERSION_')) {
exit;
}
-const API_URL = 'https://{region}-plugins.doofinder.com';
-
class DoofinderInstallation
{
- private $api_key;
- private $api_url;
+ private $apiKey;
+ private $apiUrl;
- public function __construct($api_key, $region)
+ public function __construct($apiKey, $region)
{
- $this->api_key = $api_key;
- $this->api_url = str_replace('{region}', $region, API_URL);
+ $this->apiKey = $apiKey;
+ $this->apiUrl = str_replace('{region}', $region, UrlManager::API_URL);
}
/**
@@ -37,14 +36,14 @@ public function __construct($api_key, $region)
* @param string $installation_id
* @param string $callback_url
*/
- public function is_valid_update_on_save($installation_id)
+ public function isValidUpdateOnSave($installationId)
{
- $api_endpoint = $this->api_url . '/' . $installation_id . '/validate-update-on-save';
+ $apiEndpoint = $this->apiUrl . '/' . $installationId . '/validate-update-on-save';
- return $this->get($api_endpoint);
+ return $this->_get($apiEndpoint);
}
- private function get($url)
+ private function _get($url)
{
$client = new EasyREST();
@@ -54,9 +53,257 @@ private function get($url)
false,
false,
'application/json',
- ['Authorization: Token ' . $this->api_key]
+ ['Authorization: Token ' . $this->apiKey]
);
return json_decode($response->response, true);
}
+
+ /**
+ * Install the module database tables
+ *
+ * @return bool
+ */
+ public static function installDb()
+ {
+ return \Db::getInstance()->execute(
+ '
+ CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'doofinder_updates` (
+ `id_doofinder_update` INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ `id_shop` INT(10) UNSIGNED NOT NULL,
+ `object` varchar(45) NOT NULL,
+ `id_object` INT(10) UNSIGNED NOT NULL,
+ `action` VARCHAR(45) NOT NULL,
+ `date_upd` DATETIME NOT NULL,
+ PRIMARY KEY (`id_doofinder_update`),
+ CONSTRAINT uc_shop_update UNIQUE KEY (id_shop,object,id_object)
+ ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8 ;'
+ )
+ && \Db::getInstance()->execute(
+ '
+ CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'doofinder_landing` (
+ `name` VARCHAR(45) NOT NULL,
+ `hashid` VARCHAR(45) NOT NULL,
+ `data` TEXT NOT NULL,
+ `date_upd` DATETIME NOT NULL,
+ PRIMARY KEY (`name`, `hashid`)
+ ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8 ;'
+ );
+ }
+
+ /**
+ * Start the installation process
+ * If shop_id is null, install all shops
+ *
+ * @param int $shop_id
+ *
+ * @return void
+ */
+ public static function autoinstaller($shop_id = null)
+ {
+ if (!empty($shop_id)) {
+ $shop = \Shop::getShop($shop_id);
+ self::_createStore($shop);
+
+ return;
+ }
+
+ $shops = \Shop::getShops();
+ foreach ($shops as $shop) {
+ self::_createStore($shop);
+ }
+ }
+
+ /**
+ * Create a store in Doofinder based on the Prestashop shop
+ *
+ * @param array $shop
+ *
+ * @return void
+ */
+ private static function _createStore($shop)
+ {
+ $client = new EasyREST();
+ $apikey = \Configuration::getGlobalValue('DF_AI_APIKEY');
+ $languages = \Language::getLanguages(true, $shop['id_shop']);
+ $currencies = \Currency::getCurrenciesByIdShop($shop['id_shop']);
+ $shopId = $shop['id_shop'];
+ $shopGroupId = $shop['id_shop_group'];
+ $primaryLang = new \Language(\Configuration::get('PS_LANG_DEFAULT', null, $shopGroupId, $shopId));
+ $installationID = null;
+
+ DoofinderConfig::setDefaultShopConfig($shopGroupId, $shopId);
+
+ $shopUrl = UrlManager::getShopURL($shopId);
+ $storeData = [
+ 'name' => $shop['name'],
+ 'platform' => 'prestashop',
+ 'primary_language' => $primaryLang->language_code,
+ 'site_url' => $shopUrl,
+ 'search_engines' => [],
+ 'plugin_version' => DoofinderConstants::VERSION,
+ ];
+
+ foreach ($languages as $lang) {
+ if ($lang['active'] == 0) {
+ continue;
+ }
+ foreach ($currencies as $cur) {
+ if ($cur['deleted'] == 1 || $cur['active'] == 0) {
+ continue;
+ }
+ $ciso = $cur['iso_code'];
+ $langCode = $lang['language_code'];
+ $feedUrl = UrlManager::getFeedUrl($shopId, $lang['iso_code'], $ciso);
+ $storeData['search_engines'][] = [
+ 'language' => $langCode,
+ 'currency' => $ciso,
+ 'feed_url' => $feedUrl,
+ 'callback_url' => UrlManager::getProcessCallbackUrl(),
+ ];
+ }
+ }
+
+ $jsonStoreData = json_encode($storeData);
+ DoofinderConfig::debug('Create Store Start');
+ DoofinderConfig::debug(print_r($storeData, true));
+
+ $response = $client->post(
+ UrlManager::getInstallUrl(\Configuration::get('DF_REGION')),
+ $jsonStoreData,
+ false,
+ false,
+ 'application/json',
+ ['Authorization: Token ' . $apikey]
+ );
+
+ if ($response->getResponseCode() === 200) {
+ $response = json_decode($response->response, true);
+ $installationID = @$response['installation_id'];
+ DoofinderConfig::debug('Create Store response:');
+ DoofinderConfig::debug(print_r($response, true));
+
+ if ($installationID) {
+ DoofinderConfig::debug("Set installation ID: $installationID");
+ \Configuration::updateValue('DF_INSTALLATION_ID', $installationID, false, $shopGroupId, $shopId);
+ \Configuration::updateValue('DF_ENABLED_V9', true, false, $shopGroupId, $shopId);
+ \Configuration::updateValue('DF_SHOW_LAYER', true, false, $shopGroupId, $shopId);
+ \Configuration::updateValue('DF_SHOW_LAYER_MOBILE', true, false, $shopGroupId, $shopId);
+ SearchEngine::setSearchEnginesByConfig();
+ } else {
+ DoofinderConfig::debug('Invalid installation ID');
+ exit('ko');
+ }
+ } else {
+ $error_msg = "Create Store failed with code {$response->getResponseCode()} and message '{$response->getResponseMessage()}'";
+ $response_msg = 'Response: ' . print_r($response->response, true);
+ DoofinderConfig::debug($error_msg);
+ DoofinderConfig::debug($response_msg);
+ echo $response->response;
+ exit;
+ }
+ }
+
+ public static function installTabs()
+ {
+ $tab = new \Tab();
+ $tab->active = 0;
+ $tab->class_name = 'DoofinderAdmin';
+ $tab->name = [];
+ foreach (\Language::getLanguages() as $lang) {
+ $tab->name[$lang['id_lang']] = 'Doofinder admin controller';
+ }
+ $tab->id_parent = 0;
+ $tab->module = DoofinderConstants::NAME;
+
+ return $tab->save();
+ }
+
+ public static function uninstallTabs()
+ {
+ $tabId = (int) \Tab::getIdFromClassName('DoofinderAdmin');
+ if (!$tabId) {
+ return true;
+ }
+
+ $tab = new \Tab($tabId);
+
+ return $tab->delete();
+ }
+
+ /**
+ * Remove module-dependent configuration variables
+ *
+ * @return bool
+ */
+ public static function deleteConfigVars()
+ {
+ $config_vars = [
+ 'DF_AI_ADMIN_ENDPOINT',
+ 'DF_AI_API_ENDPOINT',
+ 'DF_AI_APIKEY',
+ 'DF_API_KEY',
+ 'DF_API_LAYER_DESCRIPTION',
+ 'DF_CSS_VS',
+ 'DF_CUSTOMEXPLODEATTR',
+ 'DF_DEBUG',
+ 'DF_DEBUG_CURL',
+ 'DF_DSBL_AJAX_TKN',
+ 'DF_DSBL_DFCKIE_JS',
+ 'DF_DSBL_DFFAC_JS',
+ 'DF_DSBL_DFLINK_JS',
+ 'DF_DSBL_DFPAG_JS',
+ 'DF_DSBL_FAC_CACHE',
+ 'DF_DSBL_HTTPS_CURL',
+ 'DF_EB_LAYER_DESCRIPTION',
+ 'DF_ENABLED_V9',
+ 'DF_ENABLE_HASH',
+ 'DF_EXTRA_CSS',
+ 'DF_FACETS_TOKEN',
+ 'DF_FEATURES_SHOWN',
+ 'DF_FEED_FULL_PATH',
+ 'DF_FEED_INDEXED',
+ 'DF_FEED_MAINCATEGORY_PATH',
+ 'DF_GROUP_ATTRIBUTES_SHOWN',
+ 'DF_GS_DESCRIPTION_TYPE',
+ 'DF_GS_DISPLAY_PRICES',
+ 'DF_GS_IMAGE_SIZE',
+ 'DF_GS_PRICES_USE_TAX',
+ 'DF_INSTALLATION_ID',
+ 'DF_SHOW_LAYER',
+ 'DF_SHOW_LAYER_MOBILE',
+ 'DF_REGION',
+ 'DF_RESTART_OV',
+ 'DF_SHOW_PRODUCT_FEATURES',
+ 'DF_SHOW_PRODUCT_VARIATIONS',
+ 'DF_UPDATE_ON_SAVE_DELAY',
+ 'DF_UPDATE_ON_SAVE_LAST_EXEC',
+ 'DF_FEED_INDEXED',
+ ];
+
+ $hashid_vars = array_column(
+ \Db::getInstance()->executeS('
+ SELECT name FROM ' . _DB_PREFIX_ . "configuration where name like 'DF_HASHID_%'"),
+ 'name'
+ );
+
+ $config_vars = array_merge($config_vars, $hashid_vars);
+
+ foreach ($config_vars as $var) {
+ \Configuration::deleteByName($var);
+ }
+
+ return true;
+ }
+
+ /**
+ * Removes the database tables from the module
+ *
+ * @return bool
+ */
+ public static function uninstallDb()
+ {
+ return \Db::getInstance()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'doofinder_updates`')
+ && \Db::getInstance()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'doofinder_landing`');
+ }
}
diff --git a/lib/doofinder_layer_api.php b/lib/doofinder_layer_api.php
index f602294..220e99e 100644
--- a/lib/doofinder_layer_api.php
+++ b/lib/doofinder_layer_api.php
@@ -12,7 +12,7 @@
* @copyright Doofinder
* @license GPLv3
*/
-require_once _PS_MODULE_DIR_ . 'doofinder/lib/EasyREST.php';
+use PrestaShop\Module\Doofinder\Lib\EasyREST;
if (!defined('_PS_VERSION_')) {
exit;
diff --git a/views/js/doofinder-onboarding.js b/views/js/doofinder-onboarding.js
index 976db5d..4467cc4 100644
--- a/views/js/doofinder-onboarding.js
+++ b/views/js/doofinder-onboarding.js
@@ -25,7 +25,7 @@ $(document).ready(function () {
const doofinder_regex = /.*\.doofinder\.com/gm;
//Check that the sender is doofinder
if (!doofinder_regex.test(event.origin)) return;
- if (event.data) {
+ if (event.data && 'string' === typeof event.data) {
data = event.data.split("|");
event_name = data[0];
event_data = JSON.parse(atob(data[1]));
diff --git a/views/templates/admin/indexation_status.tpl b/views/templates/admin/indexation_status.tpl
index d2803e8..03d9df2 100644
--- a/views/templates/admin/indexation_status.tpl
+++ b/views/templates/admin/indexation_status.tpl
@@ -49,11 +49,11 @@
+