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 @@ +