jak = $jak; $this->psToken = $psToken; } /** * @return string[] All installed JPresta module names */ private static function getJPrestaModules() { $modulesName = []; $rows = JprestaUtils::dbSelectRows('SELECT name FROM `' . _DB_PREFIX_ . 'module` WHERE name LIKE \'jpresta%\' OR name IN (\'pagecache\',\'pagecachestd\')'); foreach ($rows as $row) { $modulesName[] = $row['name']; } return $modulesName; } /** * @param $psIsTest boolean true if this is a Prestashop instance for test, not production * @return boolean|string true if ok, error message if not ok */ public function attach($psIsTest) { if (function_exists('curl_init')) { $curl = curl_init(); $defaultShop = new Shop((int)Configuration::get('PS_SHOP_DEFAULT')); $post_data = array( 'action' => 'attach_module', 'ajax' => 1, 'ps_token' => $this->psToken, 'shop_url' => $defaultShop->getBaseURL(true), 'ps_version' => _PS_VERSION_, 'modules' => implode(',', self::getJPrestaModules()), 'ps_is_test' => (bool)$psIsTest ); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_URL, self::JPRESTA_PROTO . self::JPRESTA_DOMAIN . self::JPRESTA_DOMAIN_EXT . self::JPRESTA_PATH_API_LICENSES); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_HTTPHEADER, array( 'x-jpresta-account-key: ' . $this->jak )); curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); curl_setopt($curl, CURLOPT_MAXREDIRS, 5); $content = curl_exec($curl); if (false === $content) { $res = sprintf('error code %d - %s', curl_errno($curl), curl_error($curl) ); } else { $jsonContent = json_decode($content, true); if (!is_array($jsonContent) || !array_key_exists('status', $jsonContent)) { $res = 'JPresta server returned response in incorrect format'; } else { if ($jsonContent['status'] === 'ok') { $res = true; } else { if (array_key_exists('message', $jsonContent)) { $res = $jsonContent['message']; } else { $res = 'The account has not been attached for an unknown reason'; } } } } curl_close($curl); } else { $res = 'CURL must be available'; } return $res; } public function detach() { if (function_exists('curl_init')) { if (method_exists('Tools', 'refreshCACertFile')) { // Does not exist in some PS1.6 Tools::refreshCACertFile(); } $curl = curl_init(); $post_data = array( 'action' => 'detach', 'ajax' => 1, 'ps_token' => $this->psToken ); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_URL, self::JPRESTA_PROTO . self::JPRESTA_DOMAIN . self::JPRESTA_DOMAIN_EXT . self::JPRESTA_PATH_API_LICENSES); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_HTTPHEADER, array( 'x-jpresta-account-key: ' . $this->jak )); curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); curl_setopt($curl, CURLOPT_MAXREDIRS, 5); $content = curl_exec($curl); if (false === $content) { $res = sprintf('error code %d - %s', curl_errno($curl), curl_error($curl) ); JprestaUtils::addLog('PageCache | Detach JAK - ' . $res, 2); } else { $jsonContent = json_decode($content, true); if (!is_array($jsonContent) || !array_key_exists('status', $jsonContent)) { $res = 'JPresta server returned response in incorrect format'; JprestaUtils::addLog('PageCache | Detach JAK - ' . $res, 2); } else { if ($jsonContent['status'] === 'ok') { $res = true; } elseif ($jsonContent['status'] === 'jak_invalid') { if (array_key_exists('message', $jsonContent)) { JprestaUtils::addLog('PageCache | Ignored error: cannot detach JAK ' . $this->jak . ' - ' . $jsonContent['message'], 2); } else { JprestaUtils::addLog('PageCache | Ignored error: cannot detach JAK ' . $this->jak, 2); } $res = true; } else { if (array_key_exists('message', $jsonContent)) { $res = $jsonContent['message']; } else { $res = 'The account has not been detached for an unknown reason'; } JprestaUtils::addLog('PageCache | Detach JAK - ' . $res, 2); } } } curl_close($curl); } else { $res = 'CURL must be available'; } return $res; } public static function getLicensesURL() { return self::JPRESTA_PROTO . self::JPRESTA_DOMAIN_ADMIN . self::JPRESTA_DOMAIN_EXT . self::JPRESTA_PATH_URL_LICENSES; } public static function getCacheWarmerDashboardURL() { return self::JPRESTA_PROTO . self::JPRESTA_DOMAIN_CACHE_WARMER . self::JPRESTA_DOMAIN_EXT . self::JPRESTA_PATH_URL_CACHE_WARMER; } public static function getAutoconfURL() { return self::JPRESTA_PROTO . self::JPRESTA_DOMAIN_AUTOCONF . self::JPRESTA_DOMAIN_EXT . self::JPRESTA_PATH_URL_AUTOCONF; } /** * @return bool true if this Prestashop instance seems to be a clone of an other Prestashop */ public static function getPrestashopIsClone() { if (self::getJPrestaAccountKey()) { $currentPrestashopChecksum = self::getPrestashopChecksum(); $storedPrestashopChecksum = Configuration::get('jpresta_ps_checksum', null, 0, 0, false); return $currentPrestashopChecksum != $storedPrestashopChecksum; } return false; } /** * @param $isClone bool If true then a new Prestashop token is generated, if false it updates the current checksum of Prestashop */ public static function setPrestashopIsClone($isClone) { if ($isClone) { Configuration::deleteByName('jpresta_ps_token'); Configuration::deleteByName('jpresta_account_key'); self::getPrestashopToken(true); } self::setPrestashopChecksum(); } /** * Make this Prestashop instance an original one (store the current checksum as the new one) */ private static function setPrestashopChecksum() { Configuration::updateValue('jpresta_ps_checksum', self::getPrestashopChecksum(), false, 0, 0); } /** * @return string A checksum to identify the current Prestashop instance */ private static function getPrestashopChecksum() { $checksum = ''; if (Tools::version_compare(_PS_VERSION_, '1.7', '>')) { // PS1.7 $configFile = dirname(__FILE__) . '/../../../app/config/parameters.php'; if (file_exists($configFile)) { $config = require $configFile; $checksum .= $config['parameters']['database_host'] . '|'; $checksum .= $config['parameters']['database_name'] . '|'; } else { // Is it possible? $checksum .= _DB_SERVER_ . '|'; $checksum .= _DB_NAME_ . '|'; } $checksum .= JprestaUtils::dbGetValue('SELECT GROUP_CONCAT(domain, physical_uri) FROM `' . _DB_PREFIX_ . 'shop_url`;', false, false); } else { // PS1.5 PS1.6 $checksum .= _DB_SERVER_ . '|'; $checksum .= _DB_NAME_ . '|'; } return md5($checksum); } /** * @param bool $reset If true a new Prestashop token is generated * @return string A string that identify this Prestashop instance */ public static function getPrestashopToken($reset = false) { if ($reset) { Configuration::deleteByName('jpresta_ps_token'); } $token = Configuration::get('jpresta_ps_token', null, 0, 0, false); if (!$token) { // Generate a new token $token = 'PS-' . Tools::strtoupper(self::generateRandomString(12)); Configuration::updateValue('jpresta_ps_token', $token, false, 0, 0); self::setPrestashopChecksum(); } return $token; } public static function getPrestashopType() { return Configuration::get('jpresta_ps_type', null, 0, 0, null); } public static function setPrestashopType($type) { Configuration::updateValue('jpresta_ps_type', $type === 'test' ? 'test' : 'prod', false, 0, 0); } public static function getJPrestaAccountKey() { return Configuration::get('jpresta_account_key', null, 0, 0, null); } public static function setJPrestaAccountKey($key) { Configuration::updateValue('jpresta_account_key', $key, false, 0, 0); } private static function generateRandomString($length = 16) { $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; $final_rand = ''; for ($i = 0; $i < $length; $i++) { $final_rand .= $chars [rand(0, Tools::strlen($chars) - 1)]; } return $final_rand; } public static function getLatestVersion($moduleName) { $latest = null; if (!_PS_MODE_DEMO_) { $cacheFile = _PS_CACHE_DIR_ . "/jpresta-latest-$moduleName.cache.tmp"; $cacheTime = @filemtime($cacheFile); if (!$cacheTime || (time() - $cacheTime) > (24 * 60 * 60)) { $datas = self::getLatestVersionDatas($moduleName); if (is_array($datas)) { $latest = $datas; } file_put_contents($cacheFile, json_encode($latest)); } else { $latest = json_decode(Tools::file_get_contents($cacheFile, false, null, 30, true), true); } } return $latest; } private static function getLatestVersionDatas($moduleName) { $get_data = array( 'action' => 'get_latest', 'ajax' => 1, 'module_name' => $moduleName ); $url = self::JPRESTA_PROTO . self::JPRESTA_DOMAIN . self::JPRESTA_DOMAIN_EXT . self::JPRESTA_PATH_API_LICENSES . '?' . http_build_query($get_data); try { $content = Tools::file_get_contents($url); if ($content) { $jsonContent = json_decode($content, true); if (!is_array($jsonContent) || !array_key_exists('status', $jsonContent)) { $res = 'JPresta server returned response in incorrect format'; } else { if ($jsonContent['status'] === 'ok') { $res = $jsonContent['latest']; } else { if (array_key_exists('message', $jsonContent)) { $res = $jsonContent['message']; } else { $res = 'Cannot retreive latest versions for an unknown reason (status not OK but no message)'; } } } } else { $res = 'Cannot retreive latest versions for an unknown reason (empty without error)'; } } catch (Exception $e) { $res = $e->getMessage(); } return $res; } } }