@file_get_contents( $fileCtl . '.dat' ); $data = is_string( $data ) ? @unserialize( $data ) : null; $lock -> Release(); return( $data ); } function ProcessCtlData_Update( $fileCtl, $data, $clearPrev = false, $lifeCtlOpenClose = null ) { if( !$fileCtl ) return( true ); $lock = new Lock( 'pl', GetCacheDir() ); if( !$lock -> Acquire() ) { return( false ); } global $seraph_accel_g_hFileCtl; $dataPrev = @file_get_contents( $fileCtl . '.dat' ); if( $dataPrev === false ) { $lock -> Release(); return( null ); } if( $lifeCtlOpenClose === true ) { Gen::FileContentExclusive_Open( $seraph_accel_g_hFileCtl, $fileCtl, false ); if( !$seraph_accel_g_hFileCtl ) { $lock -> Release(); return( false ); } } else if( $lifeCtlOpenClose === false ) Gen::FileContentExclusive_Close( $seraph_accel_g_hFileCtl ); if( !$dataPrev || $clearPrev ) $dataPrev = array(); else $dataPrev = @unserialize( $dataPrev ); $res = @file_put_contents( $fileCtl . '.dat', @serialize( array_merge( $dataPrev, $data ) ) ) !== false; $lock -> Release(); return( $res ); } function OnAsyncTask_CacheProcessItem( $args ) { $id = (isset($args[ 'id' ])?$args[ 'id' ]:null); $siteId = Gen::SanitizeId( (isset($args[ 'siteId' ])?$args[ 'siteId' ]:null) ); if( !$id || !$siteId ) return; $dirQueue = GetCacheDir() . '/q/' . $siteId; $item = null; { $lock = new Lock( 'l', $dirQueue ); if( !$lock -> Acquire() ) return; $aInitial = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, 0 ) ); $item = $aInitial[ $id ]; $aInitial -> dispose(); $lock -> Release(); unset( $aInitial, $lock ); } if( !$item ) return; $data = Gen::GetArrField( Gen::Unserialize( (isset($item[ 'd' ])?$item[ 'd' ]:null) ), array( '' ), array() ); if( !$data ) return; { if( !isset( $data[ 'p' ] ) ) $data[ 'p' ] = ( int )(isset($item[ 'p' ])?$item[ 'p' ]:null); } $procTmLim = Gen::GetArrField( Plugin::SettGet(), array( 'cache', 'procTmLim' ), 570 ); @set_time_limit( $procTmLim + 30 ); $fileCtlDir = ProcessCtlData_GetFullPath(); if( !( $fileCtl = ProcessCtlData_Init( $fileCtlDir, array() ) ) ) { $data[ 'td' ] = 0; $data[ 'hr' ] = Gen::E_FAIL; $data[ 'r' ] = 'init:Can\'t modify files in \'' . $fileCtlDir . '\''; $item[ 'd' ] = Gen::Serialize( $data ); $lock = new Lock( 'l', $dirQueue ); if( $lock -> Acquire() ) { $aInitial = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, 0 ) ); $aDone = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, 2 ) ); unset( $aInitial[ $id ] ); $aDone[ $id ] = $item; $aInitial -> dispose(); $aDone -> dispose(); } $lock -> Release(); unset( $aInitial, $aDone, $lock ); return; } unset( $fileCtlDir ); $data[ 'pc' ] = Gen::GetFileName( $fileCtl ); $tmBegin = microtime( true ); $tmOrig = ( float )(isset($item[ 't' ])?$item[ 't' ]:null); $priorOrig = ( int )(isset($item[ 'p' ])?$item[ 'p' ]:null); $item[ 't' ] = $tmBegin; $item[ 'd' ] = Gen::Serialize( $data ); { $lock = new Lock( 'l', $dirQueue ); if( !$lock -> Acquire() ) { return; } $aInitial = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, 0 ) ); $aProgress = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, 1 ) ); $ok = true; if( $aInitial -> unsetItem( $id ) === false ) $ok = false; if( $ok && $aProgress -> setItem( $id, $item ) === false ) $ok = false; $aInitial -> dispose(); $aProgress -> dispose(); if( !$ok ) { ProcessCtlData_Del( $fileCtl ); $lock -> Release(); return; } $lock -> Release(); unset( $aInitial, $aProgress, $lock ); } $prepArgs = array( 'nonce' => hash_hmac( 'md5', '' . $tmBegin, NONCE_SALT ), '_tm' => '' . $tmBegin, 'pc' => $data[ 'pc' ] ); if( $priorOrig == -480 ) $prepArgs[ 'lrn' ] = (isset($data[ 'l' ])?$data[ 'l' ]:null); $url = add_query_arg( array( 'seraph_accel_prep' => @rawurlencode( @base64_encode( @json_encode( $prepArgs ) ) ) ), (isset($data[ 'u' ])?$data[ 'u' ]:null) ); $hdrs = (isset($data[ 'h' ])?$data[ 'h' ]:null); if( !is_array( $hdrs ) ) $hdrs = array(); { $hdrsForRequest = $hdrs; Net::GetUrlWithoutProtoEx( $url, $proto ); if( strtolower( $proto ) == 'https' ) { Net::RemoveHeader( $hdrsForRequest, 'Upgrade-Insecure-Requests' ); Net::RemoveHeader( $hdrsForRequest, 'Ssl' ); } Net::RemoveHeader( $hdrsForRequest, 'Accept-Encoding' ); Net::RemoveHeader( $hdrsForRequest, 'Cloud-Protector-Client-Ip' ); unset( $proto ); $asyncMode = OnAsyncTasksPushGetMode(); if( $asyncMode == 're' ) $requestRes = PluginRe::MakeRequest( 'GET', $url, $hdrsForRequest, 30, false ); else $requestRes = Wp::RemoteGet( $url, array( 'local' => $asyncMode == 'loc', 'redirection' => 0, 'timeout' => 30, 'sslverify' => false, 'headers' => $hdrsForRequest ) ); $tmFinish = microtime( true ); $hr = Net::GetHrFromWpRemoteGet( $requestRes, true ); $httpCode = Net::GetResponseCodeFromHr( $hr ); } $needRepeat = false; $needLrn = false; $repeatIdx = null; $skipStatus = null; $warns = null; $ctlRes = ProcessCtlData_Get( $fileCtl, $isLive ); if( Gen::GetArrField( $ctlRes, array( 'stage' ) ) ) { for( ;; ) { $tmFinish = microtime( true ); if( $tmFinish - $tmBegin > $procTmLim ) { $hr = Gen::E_TIMEOUT; $requestRes = null; break; } if( is_int( $ctlRes ) ) { $hr = $ctlRes; $requestRes = null; break; } if( $ctlRes === null ) { $hr = Gen::S_ABORTED; $requestRes = null; break; } if( Gen::GetArrField( $ctlRes, array( 'finish' ) ) ) { $skipStatus = Gen::GetArrField( $ctlRes, array( 'skip' ) ); $hr = $skipStatus ? ( Gen::StrStartsWith( $skipStatus, 'err:' ) ? Gen::E_FAIL : Gen::S_FALSE ) : Gen::S_OK; $warns = Gen::GetArrField( $ctlRes, array( 'warns' ), array() ); break; } if( !$isLive ) { $hr = Gen::E_INVALID_STATE; $requestRes = null; break; } sleep( 1 ); $ctlRes = ProcessCtlData_Get( $fileCtl, $isLive ); } } else { if( ProcessCtlData_IsAborted( $fileCtl ) ) { $hr = Gen::S_ABORTED; $requestRes = null; } else if( $httpCode && $httpCode != 500 ) { if( $httpCode == 524 || $httpCode == 522 || $httpCode == 504 || $httpCode == 503 ) if( ( $repeatIdx = (isset($data[ 'rdr' ])?$data[ 'rdr' ]:0) ) <= 3 ) $needRepeat = true; $hr = Gen::HrSuccFromFail( $hr ); } } $immediatelyPushQueue = false; $urlRedir = trim( wp_remote_retrieve_header( $requestRes, 'location' ) ); if( !$urlRedir && $skipStatus && preg_match( '@^httpCode\\:(?:301|302|307|308)\\:@', $skipStatus ) ) $urlRedir = rawurldecode( substr( $skipStatus, 13 ) ); if( $urlRedir ) { $urlRedir = remove_query_arg( array( 'seraph_accel_prep' ), $urlRedir ); if( Gen::StrStartsWith( $urlRedir, '//' ) ) { GetUrlWithoutProtoEx( $url, $proto ); $urlRedir = $proto . ':' . $urlRedir; unset( $proto ); } else if( strpos( $urlRedir, '://' ) === false ) $urlRedir = Net::GetSiteAddrFromUrl( $url, true ) . $urlRedir; if( $priorOrig !== 10 ) if( ( $redirIdx = (isset($data[ 'rdr' ])?$data[ 'rdr' ]:0) ) <= 4 ) if( CachePostPreparePageEx( $urlRedir, $siteId, $priorOrig, (isset($data[ 'p' ])?$data[ 'p' ]:null), $hdrs, $tmOrig, $redirIdx + 1, (isset($data[ 'l' ])?$data[ 'l' ]:null) ) ) $immediatelyPushQueue = true; } $data[ 'td' ] = $tmFinish - $tmBegin; if( $hr != Gen::S_OK && !$skipStatus && $httpCode ) $skipStatus = 'httpCode:' . $httpCode; if( $skipStatus ) { if( Gen::StrStartsWith( $skipStatus, 'httpCode:' ) && $urlRedir && strlen( $skipStatus ) === 12 ) $skipStatus .= ':' . rawurlencode( $urlRedir ); $data[ 'hr' ] = ( $hr = Gen::StrStartsWith( $skipStatus, 'err:' ) ? Gen::E_FAIL : Gen::S_FALSE ); $data[ 'r' ] = $skipStatus; if( $skipStatus == 'alreadyProcessing' || $skipStatus == 'lrnNeed' ) $needRepeat = true; else if( Gen::StrStartsWith( $skipStatus, 'lrnNeed:' ) ) $needLrn = substr( $skipStatus, 8 ); } else if( $hr != Gen::S_OK ) { $data[ 'hr' ] = $hr; if( is_wp_error( $requestRes ) ) $data[ 'r' ] = rawurlencode( $requestRes -> get_error_message() ) . ':' . rawurlencode( LocId::Pack( 'RequestHeadersTrace_%1$s', null, array( strip_tags( str_replace( array( '
' ), array( "\n" ), GetHeadersResString( $hdrsForRequest ) ) ) ) ) ); if( $skipStatus ) $data[ 'r' ] = $skipStatus; } if( $needLrn ) { { $lock = new Lock( 'l', $dirQueue ); if( !$lock -> Acquire() ) { return; } $aProgress = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, 1 ) ); unset( $aProgress[ $id ] ); $aProgress -> dispose(); $lock -> Release(); unset( $aProgress, $lock ); } CachePostPreparePageEx( (isset($data[ 'u' ])?$data[ 'u' ]:null), $siteId, -480, (isset($data[ 'p' ])?$data[ 'p' ]:null), $hdrs, $tmOrig, null, $needLrn ); $immediatelyPushQueue = true; } else { if( $hr == Gen::S_OK && $warns ) $data[ 'w' ] = $warns; if( isset( $data[ 'hr' ] ) && $data[ 'hr' ] != Gen::S_OK && $urlRedir && $urlRedir == (isset($data[ 'u' ])?$data[ 'u' ]:null) ) { $data[ 'hr' ] = ( $hr = Gen::E_FAIL ); $data[ 'r' ] = 'redirectToItself'; } { $lock = new Lock( 'l', $dirQueue ); if( !$lock -> Acquire() ) { return; } $aProgress = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, 1 ) ); $aDone = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, 2 ) ); { $dataExtUpdated = $aProgress[ $id ]; if( $dataExtUpdated ) { if( $dataExtUpdated = Gen::GetArrField( Gen::Unserialize( (isset($dataExtUpdated[ 'd' ])?$dataExtUpdated[ 'd' ]:null) ), array( '' ), array() ) ) if( (isset($dataExtUpdated[ 'rpt' ])?$dataExtUpdated[ 'rpt' ]:null) ) $needRepeat = true; unset( $dataExtUpdated ); } } $item[ 't' ] = $tmFinish; $item[ 'p' ] = -1000; $item[ 'd' ] = Gen::Serialize( $data ); unset( $aProgress[ $id ] ); $aDone[ $id ] = $item; $aProgress -> dispose(); $aDone -> dispose(); $lock -> Release(); unset( $aProgress, $aDone, $lock ); } } ProcessCtlData_Del( $fileCtl ); update_option( 'seraph_accel_procEndLastTime', ( int )$tmFinish, false ); if( $needRepeat && CachePostPreparePageEx( (isset($data[ 'u' ])?$data[ 'u' ]:null), $siteId, $priorOrig, (isset($data[ 'p' ])?$data[ 'p' ]:null), $hdrs, $tmOrig, $repeatIdx !== null ? ( $repeatIdx + 1 ) : null, (isset($data[ 'l' ])?$data[ 'l' ]:null) ) ) $immediatelyPushQueue = true; CachePushQueueProcessor( true, $immediatelyPushQueue, $hr != Gen::S_OK && Gen::HrSucc( $hr ) ); } function GetHeadersResString( $hdrs ) { $res = ''; foreach( $hdrs as $hdrId => $hdrVals ) { if( !is_array( $hdrVals ) ) $hdrVals = array( $hdrVals ); foreach( $hdrVals as $hdrVal ) { if( $res ) $res .= '
'; $res .= Ui::Tag( 'em', htmlspecialchars( $hdrId ) ) . ': ' . htmlspecialchars( $hdrVal ); } } return( $res ); } function CacheInitQueueTable( $force = false ) { $data = Plugin::DataGet(); $dbVer = Gen::GetArrField( $data, 'queueDbVer', 0 ); if( !$force && $dbVer == QUEUE_DB_VER ) return; Gen::SetArrField( $data, 'queueDbVer', QUEUE_DB_VER ); Plugin::DataSet( $data ); if( $dbVer && $dbVer < 4 ) { $nRowsChunk = 100; $dbtran = new Lock( 'ql', GetCacheDir() ); if( $dbtran -> Acquire() ) { $run = true; $tmStart = time(); foreach( array( 2, 1, 0 ) as $state ) { for( $i = 0; ; $i++ ) { $items = DbTbl::GetRows( Db::GetTblPrefix( 'seraph_accel_queue' ), null, array( $i * $nRowsChunk, $nRowsChunk ), array( 'state' => $state ) ); if( !$items ) break; foreach( $items as $itemFromDb ) { $id = @hex2bin( (isset($itemFromDb[ 'id' ])?$itemFromDb[ 'id' ]:null) ); $siteId = (isset($itemFromDb[ 'site_id' ])?$itemFromDb[ 'site_id' ]:null); if( !$siteId ) $siteId = 'm'; $item = array( 'p' => ( int )(isset($itemFromDb[ 'prior' ])?$itemFromDb[ 'prior' ]:null), 't' => ( float )(isset($itemFromDb[ 'tm' ])?$itemFromDb[ 'tm' ]:null), 'd' => (isset($itemFromDb[ 'data' ])?$itemFromDb[ 'data' ]:null) ); { $dirQueue = GetCacheDir() . '/q/' . $siteId; $lock = new Lock( 'l', $dirQueue ); if( $lock -> Acquire() ) { $a = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, $state ) ); $a[ $id ] = $item; $a -> dispose(); unset( $a ); $lock -> Release(); } unset( $lock ); } if( time() - $tmStart > 10 ) { $run = false; break; } } if( !$run ) break; } if( !$run ) break; } DbTbl::DeleteRows( Db::GetTblPrefix( 'seraph_accel_queue' ) ); $dbtran -> Release(); } } } function GetViewDeviceGrpNameFromData( $viewsDeviceGrp ) { $viewName = (isset($viewsDeviceGrp[ 'name' ])?$viewsDeviceGrp[ 'name' ]:null); if( !$viewName ) $viewName = 'id:' . (isset($viewsDeviceGrp[ 'id' ])?$viewsDeviceGrp[ 'id' ]:null); return( $viewName ); } function _CachePostPreparePageEx_StopAndRepeat( $aProgress, $id, $data = null ) { $item = $aProgress[ $id ]; if( !$item ) return; $itemInProgressData = Gen::GetArrField( Gen::Unserialize( (isset($item[ 'd' ])?$item[ 'd' ]:null) ), array( '' ), array() ); if( (isset($itemInProgressData[ 'rpt' ])?$itemInProgressData[ 'rpt' ]:null) || !( $fileCtl = ProcessCtlData_GetFullPath( (isset($itemInProgressData[ 'pc' ])?$itemInProgressData[ 'pc' ]:null) ) ) ) return; ProcessCtlData_Del( $fileCtl ); if( $data ) $itemInProgressData = array_merge( $data, $itemInProgressData ); $itemInProgressData[ 'rpt' ] = true; $item[ 'd' ] = Gen::Serialize( $itemInProgressData ); $aProgress[ $id ] = $item; } function CachePostPreparePageEx( $url, $siteId, $priority, $priorityInitiator, $headers = null, $time = null, $redirIdx = null, $lrnId = null ) { if( !$url ) return( false ); if( $priority == -480 && !$lrnId ) return( false ); if( $priorityInitiator === null ) $priorityInitiator = $priority; $settCache = Gen::GetArrField( Plugin::SettGet(), array( 'cache' ), array() ); if( $time === null ) $time = microtime( true ); if( !is_array( $headers ) ) $headers = array(); $id = $url . $priority; $idLearn = $url . -480; foreach( $headers as $header => $headerVal ) { $headerVal = $header . ( is_array( $headerVal ) ? implode( '', $headerVal ) : $headerVal ); $id .= $headerVal; $idLearn .= $headerVal; } $id = md5( $id, true ); $idLearn = md5( $idLearn, true ); $viewName = null; if( $viewsDeviceGrp = GetCacheViewDeviceGrp( $settCache, strtolower( (isset($headers[ 'User-Agent' ])?$headers[ 'User-Agent' ]:null) ) ) ) $viewName = GetViewDeviceGrpNameFromData( $viewsDeviceGrp ); $dirQueue = GetCacheDir() . '/q/' . $siteId; if( $priority == 10 ) { $count = 0; { $lock = new Lock( 'l', $dirQueue ); if( $lock -> Acquire() ) { $aInitial = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, 0 ) ); $count = $aInitial -> count(); $aInitial -> dispose(); $lock -> Release(); } unset( $aInitial, $lock ); } if( $count > 1000 ) { return( null ); } } $data = array( 'p' => $priorityInitiator, 'u' => $url, 'h' => $headers, 'v' => $viewName ); if( $redirIdx ) $data[ 'rdr' ] = $redirIdx; if( $lrnId ) $data[ 'l' ] = $lrnId; { $lock = new Lock( 'l', $dirQueue ); if( !$lock -> Acquire() ) { return( false ); } $aInitial = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, 0 ) ); $aProgress = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, 1 ) ); $aDone = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, 2 ) ); unset( $aDone[ $id ] ); $res = false; if( !isset( $aProgress[ $id ] ) ) { $aInitial[ $id ] = array( 'p' => $priority, 't' => $time, 'd' => Gen::Serialize( $data ) ); $res = true; } if( $priority !== 10 ) { _CachePostPreparePageEx_StopAndRepeat( $aProgress, $id, $data ); if( $id != $idLearn ) _CachePostPreparePageEx_StopAndRepeat( $aProgress, $idLearn ); } $aInitial -> dispose(); $aProgress -> dispose(); $aDone -> dispose(); $lock -> Release(); unset( $aInitial, $aProgress, $aDone, $lock ); } return( $res ); } function CacheQueueDelete( $siteId ) { $res = true; foreach( ( $siteId ? array( $siteId ) : GetSiteIds() ) as $siteIdEnum ) { $dirQueue = GetCacheDir() . '/q/' . $siteIdEnum; $lock = new Lock( 'l', $dirQueue ); if( !$lock -> Acquire() ) { $res = false; continue; } $aInitial = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, 0 ) ); $aDone = new ArrayOnFiles( Queue_GetStgPrms( $dirQueue, 2 ) ); $aInitial -> clear(); $aDone -> clear(); $aInitial -> dispose(); $aDone -> dispose(); $lock -> Release(); unset( $aInitial, $aDone, $lock ); } return( $res ); } function GetExtContents( $url, &$contMimeType = null, $userAgentCmn = true, $timeout = 30, $rememberServerState = true ) { $args = array( 'sslverify' => false, 'timeout' => $timeout ); if( $userAgentCmn ) $args[ 'user-agent' ] = 'Mozilla/99999.9 AppleWebKit/9999999.99 (KHTML, like Gecko) Chrome/999999.0.9999.99 Safari/9999999.99 seraph-accel-Agent/2.21.1'; global $seraph_accel_g_aGetExtContentsFailedSrvs; if( $serverId = Net::UrlParse( $url ) ) $serverId = Net::UrlDeParse( $serverId, 0, array( PHP_URL_USER, PHP_URL_PASS, PHP_URL_PATH, PHP_URL_QUERY, PHP_URL_FRAGMENT ) ); if( $rememberServerState && $serverId && Gen::HrFail( (isset($seraph_accel_g_aGetExtContentsFailedSrvs[ $serverId ])?$seraph_accel_g_aGetExtContentsFailedSrvs[ $serverId ]:null) ) ) return( false ); $res = Wp::RemoteGet( $url, $args ); $hr = Net::GetHrFromWpRemoteGet( $res ); if( Gen::HrFail( $hr ) ) { if( $rememberServerState && ( $hr == Gen::E_TIMEOUT || $hr == Net::E_TIMEOUT ) && $serverId ) $seraph_accel_g_aGetExtContentsFailedSrvs[ $serverId ] = $hr; return( false ); } $contMimeType = ( string )wp_remote_retrieve_header( $res, 'content-type' ); if( ( $nPos = strpos( $contMimeType, ';' ) ) !== false ) $contMimeType = substr( $contMimeType, 0, $nPos ); $contMimeType = trim( $contMimeType ); return( wp_remote_retrieve_body( $res ) ); } function CacheExtractPreparePageParams( &$args ) { $prms = (isset($args[ 'seraph_accel_prep' ])?$args[ 'seraph_accel_prep' ]:null); if( !$prms ) return( null ); Net::CurRequestRemoveArgs( $args, array( 'seraph_accel_prep' ) ); $prms = @json_decode( @base64_decode( Gen::SanitizeTextData( $prms ) ), true ); if( hash_hmac( 'md5', '' . (isset($prms[ '_tm' ])?$prms[ '_tm' ]:null), NONCE_SALT ) != (isset($prms[ 'nonce' ])?$prms[ 'nonce' ]:null) ) return( false ); unset( $prms[ '_tm' ] ); unset( $prms[ 'nonce' ] ); if( isset( $prms[ 'pc' ] ) ) $prms[ 'pc' ] = ProcessCtlData_GetFullPath( $prms[ 'pc' ] ); if( isset( $_SERVER[ 'HTTP_X_SERAPH_ACCEL_GEO_REMOTE_ADDR' ] ) ) $_SERVER[ 'REMOTE_ADDR' ] = $_SERVER[ 'HTTP_X_SERAPH_ACCEL_GEO_REMOTE_ADDR' ]; return( $prms ); } function GetCacheViewDeviceGrp( $settCache, $userAgent ) { if( !(isset($settCache[ 'views' ])?$settCache[ 'views' ]:null) ) return( null ); $viewsDeviceGrps = Gen::GetArrField( $settCache, array( 'viewsDeviceGrps' ), array() ); foreach( $viewsDeviceGrps as $viewsDeviceGrp ) { if( !(isset($viewsDeviceGrp[ 'enable' ])?$viewsDeviceGrp[ 'enable' ]:null) ) continue; $a = implode( ' ', Gen::GetArrField( $viewsDeviceGrp, array( 'agents' ), array() ) ); if( $a && strpos( $userAgent, $a ) !== false ) return( $viewsDeviceGrp ); } foreach( $viewsDeviceGrps as $viewsDeviceGrp ) { if( !(isset($viewsDeviceGrp[ 'enable' ])?$viewsDeviceGrp[ 'enable' ]:null) ) continue; if( MatchUserAgentExpressions( $userAgent, Gen::GetArrField( $viewsDeviceGrp, array( 'agents' ), array() ) ) ) return( $viewsDeviceGrp ); } return( null ); } function GetCurHdrsToStoreInCache( $settCache ) { $res = array(); $hdrPatterns = (isset($settCache[ 'hdrs' ])?$settCache[ 'hdrs' ]:null); if( !$hdrPatterns ) return( $res ); foreach( headers_list() as $hdr ) { foreach( $hdrPatterns as $hdrPattern ) { if( @preg_match( $hdrPattern, $hdr ) ) { $res[] = $hdr; break; } } } return( $res ); } function LastWarnDscs_Add( $txt ) { global $seraph_accel_g_aLastWarnDsc; $seraph_accel_g_aLastWarnDsc[] = $txt; } function LastWarnDscs_Get() { global $seraph_accel_g_aLastWarnDsc; return( $seraph_accel_g_aLastWarnDsc !== null ? $seraph_accel_g_aLastWarnDsc : array() ); } function _SetExpirableOption( $option, $value, $timeout ) { update_option( $option, $value, false ); update_option( $option . '_tmMax', time() + $timeout, false ); } function _DelExpirableOption( $option ) { delete_option( $option ); delete_option( $option . '_tmMax' ); } function _DelExpiredOption( $option ) { $tmMax = get_option( $option . '_tmMax' ); if( $tmMax && $tmMax < time() ) _DelExpirableOption( $option ); } function GetCountryCodeByIp( $settCache, &$ip_address ) { $country_code = '^'; if( !class_exists( 'MaxMind\\Db\\Reader' ) ) return( $country_code ); try { $reader = new \MaxMind\Db\Reader( Gen::GetArrField( $settCache, array( 'viewsGeo', 'fileMmDb' ), '' ) ); $data = $reader -> get( $ip_address ); if( isset( $data[ 'country' ][ 'iso_code' ] ) ) $country_code = strtoupper( $data[ 'country' ][ 'iso_code' ] ); $reader -> close(); } catch( \Exception $e ) { } return( $country_code ); } function GetViewGeoIdByIp( $settCache, &$ip ) { $countryCode = GetCountryCodeByIp( $settCache, $ip ); $viewGeoId = null; $grpIsFirst = true; $countryCodeForce = null; foreach( Gen::GetArrField( $settCache, array( 'viewsGeo', 'grps' ), array() ) as $grpId => $grp ) { if( !(isset($grp[ 'enable' ])?$grp[ 'enable' ]:null) ) continue; $matched = false; $countryCodeFirstTmp = null; foreach( Gen::GetArrField( $grp, array( 'items' ), array() ) as $grpItem ) { $aa = ExprConditionsSet_Parse( $grpItem ); if( $countryCodeFirstTmp === null && ExprConditionsSet_IsTrivial( $aa ) ) $countryCodeFirstTmp = $grpItem; foreach( $aa as $a ) { $v = null; if( IsStrRegExp( $a[ 'expr' ] ) ) { if( @preg_match( $a[ 'expr' ], $countryCode ) ) $v = $countryCode; } else if( $countryCode === $a[ 'expr' ] ) $v = $countryCode; $matched = ExprConditionsSet_ItemOp( $a, $v ); if( !$matched ) break; } if( $matched ) break; } if( $matched ) { $viewGeoId = $grpIsFirst ? '' : $grpId; $countryCodeForce = $countryCodeFirstTmp; break; } $grpIsFirst = false; } if( $viewGeoId === null ) $viewGeoId = $countryCode; if( $countryCodeForce ) { static $g_aRegIpDef = array( 'IN' => '165.22.217.1', 'BG' => '195.123.228.1', 'US' => '161.35.130.1', ); if( isset( $g_aRegIpDef[ $countryCodeForce ] ) ) $ip = $g_aRegIpDef[ $countryCodeForce ]; } return( $viewGeoId ); } function DepsExpand( $a, $bExpand = true ) { $aRes = array(); foreach( $a as $type => $aId ) $aRes[ $type ] = $bExpand ? array_fill_keys( $aId, array() ) : array_keys( $aId ); return( $aRes ); } function DepsDiff( $a, $aNew ) { $aRes = array_diff_key( $aNew, $a ); foreach( $a as $type => $aoiCi ) $aRes[ $type ] = array_diff_key( Gen::GetArrField( $aNew, array( $type ), array() ), $aoiCi ); return( $aRes ); } function DepsAdd( &$a, $type, $oiCi ) { $a[ $type ][ $oiCi ] = array(); } function DepsRemove( &$a, $aRem ) { foreach( $aRem as $type => $aoiCi ) { foreach( $aoiCi as $oiCi => $v ) unset( $a[ $type ][ $oiCi ] ); if( isset( $a[ $type ] ) && !count( $a[ $type ] ) ) unset( $a[ $type ] ); } } function LogGetRelativeFile() { static $g_fileRel; if( $g_fileRel === null ) $g_fileRel = '/logs/log.' . Gen::GetNonce( 'logFileSfx', NONCE_SALT ) . '.txt'; return( $g_fileRel ); } function LogWrite( $text, $severity = Ui::MsgInfo, $category = 'DEBUG' ) { Gen::LogWrite( GetCacheDir() . LogGetRelativeFile(), $text, $severity, $category ); }