getOrSet(static::CACHE_KEY, function () use ($proxy) { return $proxy->getFilteredProxyAfterDownloading(); }, static::CACHE_TTL); } /** * Скачивает и возвращает список прокси * * @return array прокси * @throws Exception */ protected function getFilteredProxyAfterDownloading() { $path = $this->download(); return $this->getFilteredArrayFromFile($path); } /** * Скачивает файл со списом прокси * * @return bool|string * @throws Exception */ protected function download() { $downloadedFilePath = static::PROXY_FILE_DOWNLOAD_FOLDER . 'proxies' . uniqid(true) . '.txt'; $fp = fopen($downloadedFilePath, 'w+'); if($fp === false) { throw new Exception('Could not open: ' . $downloadedFilePath); } $ch = curl_init(static::PROXY_FILE_DOWNLOAD_URL); curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_TIMEOUT, 20); curl_exec($ch); if (curl_errno($ch)) { $this->reportFailure(static::DOWNLOAD_FAILURE_MESSAGE, curl_error($ch)); } $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if($statusCode == 200) { return $downloadedFilePath; } else { $this->reportFailure(static::DOWNLOAD_FAILURE_MESSAGE, $statusCode); return false; } } /** * Получаем и фильтруем прокси из файла * * @param String $path путь к файлу прокси * @return array */ protected function getFilteredArrayFromFile($path) { $lines = file($path); $lineCount = count($lines); $proxies = []; foreach ($lines as $lineNumber => $line) { if ($lineNumber > 3 && $lineNumber < $lineCount - 2) { $proxies[] = $line; } } //Filter out proxies by country $proxies = array_filter($proxies, function($proxy) { $description = explode(' ', $proxy)[1]; $countryCode = explode('-', $description)[0]; return in_array($countryCode, static::PROXY_COUNTRIES); }); // Get proxies only, without other data return array_map(function($proxy) { return explode(' ', $proxy)[0]; }, $proxies); } /** * Удалем прокси из кэша * * @param $proxy * @return bool */ public static function removeFromCache($proxy) { $proxies = FileCache::init()->get(static::CACHE_KEY); if (($key = array_search($proxy, $proxies)) !== false) { unset($proxies[$key]); return FileCache::init()->set(static::CACHE_KEY, $proxies, null, static::CACHE_TTL); } return false; } /** * Отправляет сообщение об ошибке * * @param string $theme тема email * @param mixed $data данные по ошибке */ protected function reportFailure($theme, $data) { $body = json_encode($data, true); sender::sendEmail(static::FAILURE_REPORT_EMAILS, $body, $theme); } }