token = $token; $this->slug = $slug; $this->httpClient = new HttpClient(); $this->fill(); } private function fill(): void { $ip = $this->getIp(); $ua = $_SERVER['HTTP_USER_AGENT'] ?? ''; $referer = $_SERVER['HTTP_REFERER'] ?? ''; $language = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? ''; $query = $_GET ?? []; $this ->token($this->token) ->slug($this->slug) ->ip($ip) ->userAgent($ua) ->referer($referer) ->domain($this->getCurrentUrl()) ->query($query) ->language($language); } public function debug() { $this->debug = true; $GLOBALS['cloakup_debug'] = true; return $this; } private function param($key, $value): self { if (empty($this->params[$key]) && !in_array($key, $this->reservedParams)) { $this->params[$key] = $value; } return $this; } private function getIp(): string { $ip = null; $headers = [ 'HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_FORWARDED', 'HTTP_CLIENT_IP', 'HTTP_X_REAL_IP', ]; foreach ($headers as $header) { if (isset($_SERVER[$header])) { $ip = $_SERVER[$header]; break; } } if ($ip === null) { $ip = $_SERVER['REMOTE_ADDR']; } return $ip; } private function getCurrentUrl(): string { $scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http'; $host = $_SERVER['HTTP_HOST'] ?? ''; $uri = explode('?', $_SERVER['REQUEST_URI'])[0] ?? ''; return "$scheme" . "://$host" . "$uri"; } private function slug($slug) { $this->params['slug'] = $slug; return $this; } private function token($token) { $this->params['token'] = $token; return $this; } private function ip($ip): self { $this->params['ip'] = $ip; return $this; } private function userAgent($ua): self { $this->params['user_agent'] = $ua; return $this; } private function referer($referer): self { $this->params['referer'] = $referer; return $this; } private function domain($domain): self { $this->params['domain'] = $domain; return $this; } private function language($language): self { $this->params['language'] = $language; return $this; } private function query($query): self { $this->params['query'] = $query; return $this; } private function getCookies(): string { return $_SERVER['HTTP_COOKIE'] ?? ''; } private function startSession(): void { if (session_status() === PHP_SESSION_NONE) { session_start([ 'cookie_lifetime' => $this->getSessionTtl() * 60 * 60, 'name' => self::SESSION_KEY, ]); } } private function saveState($params): void { $this->startSession(); $_SESSION[self::SESSION_KEY] = json_encode($params); } private function storeCookies(): void { $cookies = $this->response->cookies ?? []; if (empty($cookies)) { return; } foreach ($cookies as $cookie) { $this->setCookie($cookie->name, $cookie->value, $cookie->ttl); } } private function setCookie($key, $value, $ttl): void { if (isset($_COOKIE[$key]) && $_COOKIE[$key] == $value) { return; } setcookie($key, $value, time() + ($ttl * 60 * 60), '/'); $_COOKIE[$key] = $value; } private function setHeaders(): void { $headers = $this->response->headers ?? []; if (empty($headers)) { return; } foreach ($headers as $header) { header($header->name . ': ' . $header->value); } } private function getSessionTtl(): int { return $this->response->ttl ?? self::SESSION_TTL; } private function getRequestUrl(): string { $endpoint = self::BASE_URL . $this->getEndpoint(); return str_replace( ['{version}'], [self::VERSION], $endpoint ); } private function getEndpoint(): string { return self::FILTER_URL; } private function getRequestParams(): array { return $this->params; } private function getRequestOptions(): array { return [ 'cookie' => $this->getCookies(), ]; } private function buildUrl($url, $params, $remove = []): string { if (empty($params)) { return $url; } foreach ($remove as $key) { unset($params[$key]); } $query = http_build_query($params); return $url . (strpos($url, '?') === false ? '?' : '&') . $query; } private function getContextOptions() { return stream_context_create([ 'ssl' => ['verify_peer' => false, 'verify_peer_name' => false], 'http' => ['header' => 'User-Agent: ' . $this->params['user_agent']], ]); } public function execute(): self { $url = $this->getRequestUrl(); $params = $this->getRequestParams(); $options = $this->getRequestOptions(); try { $response = $this->httpClient->request( $url, $params, $options ); } catch (Exception $e) { throw new CloakupClientException($e->getMessage(), $e->getCode()); if ($this->debug) { throw $e; } else { echo $e->getMessage(); die; } } $this->response = json_decode($response); $this->saveState($this->response); $this->storeCookies(); $this->setHeaders(); return $this; } private function getHtml(): string { if ($this->debug) { return json_encode($this->response); } if (empty($this->response)) { return ''; } $content = $this->response->next->content ?? ''; $type = $this->response->next->type ?? ''; $params = $this->response->params ?? []; $html = ''; if ($type === self::ACTION_REDIRECT) { $url = $this->buildUrl($content, $_GET, $params); header('Location: ' . $url, true, 303); die; } if ($type === self::ACTION_CONTENT) { if (filter_var($content, FILTER_VALIDATE_URL)) { $html = file_get_contents($content, false, $this->getContextOptions()); if (substr($content, -1) !== '/') { $content .= '/'; } $html = str_replace('
', '