1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
site_checker.php
См. документацию.
1<?php
2
6
8{
9 const MIN_PHP_VER = '8.1.0';
10
12 public $percent;
16 public $result;
18 public $LogResult;
21 public $test_percent = 0;
22 public $strError = '';
23 public $timeout = 10; // sec for one step
24 public $strResult = '';
25 public $step;
26 public $fix_mode;
27 public $cafile;
29 public $host;
30 public $ssl;
31 public $port;
32 public $arTest = [];
33 public $function;
34 public $LogFile;
35
36 public function __construct($step = 0, $fast = 0, $fix_mode = 0)
37 {
38 $this->step = intval($step);
39 if (!$this->step)
40 {
41 $this->arTestVars['site_checker_success'] = 'Y';
42 }
43 $this->fix_mode = intval($fix_mode);
44 $this->cafile = $_SERVER['DOCUMENT_ROOT'] . '/bitrix/tmp/cacert.pem';
45 $this->force_repair = defined('SITE_CHECKER_FORCE_REPAIR') && SITE_CHECKER_FORCE_REPAIR === true;
46
47 $this->host = isset($_REQUEST['HTTP_HOST']) && $_REQUEST['HTTP_HOST'] ? $_REQUEST['HTTP_HOST'] : 'localhost';
48 if (!$fix_mode) // no need to know the host in fix mode
49 {
50 if (!preg_match('/^[a-z0-9.\-]+$/i', $this->host)) // cyrillic domain hack
51 {
52 $converter = new CBXPunycode();
53 $this->host = $converter->Encode($this->host);
54 }
55 }
56 $this->ssl = isset($_REQUEST['HTTPS']) && $_REQUEST['HTTPS'] == 'on';
57 $this->port = isset($_REQUEST['SERVER_PORT']) && $_REQUEST['SERVER_PORT'] ? $_REQUEST['SERVER_PORT'] : ($this->ssl ? 443 : 80);
58
59 $arTestGroup = [];
60 $arGroupName = [];
61
62 $arGroupName[1] = IsModuleInstalled('intranet') ? GetMessage("MAIN_SC_GENERAL") : GetMessage("MAIN_SC_GENERAL_SITE");
63 $arGroupDesc[1] = GetMessage("MAIN_SC_REQUIRED_MODS_DESC");
64 $arTestGroup[1] = [
65 ['check_php_modules' => GetMessage('SC_T_MODULES')],
66 ['check_php_settings' => GetMessage('SC_T_PHP')],
67 ['check_security' => GetMessage('SC_T_APACHE')],
68 ['check_server_vars' => GetMessage('SC_T_SERVER')],
69 ['check_session' => GetMessage('SC_T_SESS')],
70 ['check_mbstring' => GetMessage('SC_T_MBSTRING')],
71 ['check_install_scripts' => GetMessage('SC_T_INSTALL_SCRIPTS')],
72 ['check_socket' => GetMessage('SC_T_SOCK')],
73 ['check_bx_crontab' => GetMessage("MAIN_SC_AGENTS_CRON")],
74 ];
75
76 $arGroupName[2] = GetMessage("MAIN_SC_BUSINESS");
77 $arGroupDesc[2] = GetMessage("MAIN_SC_CORRECT_DESC");
78 $arTestGroup[2] = [
79 ['check_pull_stream' => GetMessage("MAIN_SC_TEST_PUSH_SERVER")],
80 ['check_pull_comments' => GetMessage("MAIN_SC_TEST_COMMENTS")],
81 ['check_turn' => GetMessage("MAIN_SC_TEST_VIDEO")],
82 ['check_access_mobile' => GetMessage("MAIN_SC_TEST_MOBILE")],
83 ['check_push_bitrix' => GetMessage("MAIN_SC_TEST_PUSH")],
84 ['check_access_docs' => GetMessage("MAIN_SC_TEST_DOCS")],
85 ['check_fast_download' => GetMessage("MAIN_SC_TEST_FAST_FILES_MSGVER_1")],
86 ['check_search' => GetMessage("MAIN_SC_TEST_SEARCH_CONTENTS")],
87 ['check_mail' => GetMessage("MAIN_SC_MAIL_TEST")],
88 ['check_ca_file' => GetMessage("MAIN_SC_CLOUD_TEST")],
89 ['check_connect_mail' => GetMessage("MAIN_SC_TEST_MAIL_INTEGRATION")],
90 ['check_socnet' => GetMessage("MAIN_SC_TEST_SOCNET_INTEGRATION")],
91 ['check_rest' => GetMessage("MAIN_SC_TEST_REST")],
92 ['check_mail_push' => GetMessage("MAIN_SC_TEST_MAIL_PUSH")],
93 ];
94 if (IsModuleInstalled('extranet'))
95 {
96 $arTestGroup[2][] = ['check_extranet' => GetMessage("MAIN_SC_EXTRANET_ACCESS")];
97 }
98
99 $arGroupName[4] = GetMessage("MAIN_SC_WINDOWS_ENV");
100 $arGroupDesc[4] = '';
101 $arTestGroup[4] = [
102 ['check_webdav' => GetMessage("MAIN_SC_DOCS_EDIT_MS_OFFICE")],
103 ['check_socket_ssl' => GetMessage("MAIN_SC_EXTERNAL_APPS_TEST")],
104 ['check_ad' => GetMessage("MAIN_SC_TEST_LDAP")],
105 ['check_ntlm' => GetMessage("MAIN_SC_TEST_NTLM")],
106 ];
107
108 $arGroupName[8] = GetMessage("MAIN_SC_PERFORM");
109 $arGroupDesc[8] = '';
110 $arTestGroup[8] = [
111 ['check_perf' => GetMessage("MAIN_SC_PERF_TEST")],
112 ['check_compression' => GetMessage("MAIN_SC_COMPRESSION_TEST")],
113 ];
114
115 $arGroupName[16] = GetMessage('SC_GR_EXTENDED');
116 $arTestGroup[16] = [
117 ['check_dbconn' => GetMessage('SC_T_DBCONN')],
118 ['check_session_ua' => GetMessage('SC_T_SESS_UA')],
119 ['check_sites' => GetMessage('SC_T_SITES')],
120
121 ['check_pcre_recursion' => GetMessage('SC_T_RECURSION')],
122
123 ['check_upload' => GetMessage('SC_T_UPLOAD')],
124 ['check_upload_big' => GetMessage('SC_T_UPLOAD_BIG')],
125 ['check_upload_raw' => GetMessage('SC_T_UPLOAD_RAW')],
126 ['check_post' => GetMessage('SC_T_POST')],
127
128 ['check_mail' => GetMessage('SC_T_MAIL')],
129 ['check_mail_big' => GetMessage('SC_T_MAIL_BIG')],
130 ['check_mail_b_event' => GetMessage('SC_T_MAIL_B_EVENT')],
131
132 ['check_localredirect' => GetMessage('SC_T_REDIRECT')],
133 ['check_memory_limit' => GetMessage('SC_T_MEMORY')],
134 ['check_cache' => GetMessage('SC_T_CACHE')],
135
136 ['check_update' => GetMessage('SC_UPDATE_ACCESS')],
137 ['check_http_auth' => GetMessage('SC_T_AUTH')],
138 ['check_exec' => GetMessage('SC_T_EXEC')],
139 ['check_getimagesize' => GetMessage('SC_T_GETIMAGESIZE')],
140 ];
141
142 $arGroupName[32] = GetMessage('SC_GR_MYSQL');
143 $arTestGroup[32] = [
144 ['check_mysql_bug_version' => GetMessage('SC_T_MYSQL_VER')],
145 ['check_mysql_time' => GetMessage('SC_T_TIME')],
146 ['check_mysql_mode' => GetMessage('SC_T_SQL_MODE')],
147 ['check_mysql_connection_charset' => GetMessage('SC_CONNECTION_CHARSET')],
148 ['check_mysql_db_charset' => GetMessage('SC_DB_CHARSET')],
149 ['check_mysql_table_format' => GetMessage('SC_T_FORMAT')],
150 ['check_mysql_table_charset' => GetMessage('SC_T_CHARSET')],
151 ['check_mysql_table_structure' => GetMessage('SC_T_STRUCTURE')],
152 ];
153
154 $arGroupName[64] = GetMessage('SC_GR_MYSQL');
155 $arTestGroup[64] = [
156 ['check_pgsql_version' => GetMessage('SC_T_PGSQL_VER')],
157 ['check_mysql_time' => GetMessage('SC_T_TIME')],
158 ['check_pgsql_db_charset' => GetMessage('SC_DB_CHARSET')],
159 ['check_pgsql_connection_charset' => GetMessage('SC_CONNECTION_CHARSET')],
160 ];
161
162 if ($this->fix_mode)
163 {
164 switch ($this->fix_mode)
165 {
166 case 1:
167 $this->arTest = [
168 ['check_mysql_table_status' => GetMessage('SC_T_CHECK')],
169 ];
170 break;
171 case 2:
172 $this->arTest = [
173 ['check_mysql_connection_charset' => GetMessage('SC_CONNECTION_CHARSET')],
174 ['check_mysql_db_charset' => GetMessage('SC_DB_CHARSET')],
175 ['check_mysql_table_format' => GetMessage('SC_T_FORMAT')],
176 ['check_mysql_table_charset' => GetMessage('SC_T_CHARSET')],
177 ['check_mysql_table_structure' => GetMessage('SC_T_STRUCTURE')],
178 ];
179 break;
180 case 3:
181 $this->arTest = [
182 ['check_mysql_table_structure' => GetMessage('SC_T_STRUCTURE')],
183 ];
184 break;
185 case 4:
186 $this->arTest = [
187 ['check_mbstring' => GetMessage('SC_T_MBSTRING')],
188 ];
189 break;
190 default:
191 $this->arTest = [
192 ['check_server_vars' => GetMessage('SC_T_SERVER')],
193 ];
194 break;
195 }
196 }
197 else
198 {
199 $profile = 1;
200 if ($fast)
201 {
202 if (IsModuleInstalled('intranet'))
203 {
204 $profile |= 2;
205 $profile |= 4;
206 $profile |= 8;
207 }
208 }
209 else
210 {
211 $profile |= 16;
212 switch (Application::getConnection()->getType())
213 {
214 case 'mysql':
215 $profile |= 32;
216 break;
217 case 'pgsql':
218 $profile |= 64;
219 break;
220 }
221 }
222 $this->arTest = [];
223 $step0 = $step;
224 foreach ($arTestGroup as $i => $ar)
225 {
226 if ($i & $profile)
227 {
228 if (!$this->group_name)
229 {
230 $c = count($ar);
231 if ($step0 >= $c)
232 {
233 $step0 -= $c;
234 }
235 else
236 {
237 $this->group_name = $arGroupName[$i] ?? '';
238 $this->group_desc = $arGroupDesc[$i] ?? '';
239 }
240 }
241 $this->arTest = array_merge($this->arTest, $ar);
242 }
243 }
244 }
245
246 $this->function = key($this->arTest[$this->step]);
247 $this->strCurrentTestName = current($this->arTest[$this->step]);
248 $this->strNextTestName = $this->strCurrentTestName;
249
250 $LICENSE_KEY = '';
251 if (file_exists($file = $_SERVER['DOCUMENT_ROOT'] . '/bitrix' . '/license_key.php'))
252 {
253 include($file);
254 }
255 if ($LICENSE_KEY == '')
256 {
257 $LICENSE_KEY = 'DEMO';
258 }
259 if (!defined('LICENSE_HASH'))
260 {
261 define('LICENSE_HASH', md5('CONNECTION_TEST'));
262 }
263 $this->LogFile = '/bitrix' . '/site_checker_' . md5('SITE_CHECKER' . $LICENSE_KEY) . '.log';
264 }
265
266 public static function GetTestList()
267 {
268 $ar = [];
269 foreach (get_class_methods('CSiteCheckerTest') as $method)
270 {
271 if (str_starts_with($method, 'check_'))
272 {
273 $ar[] = $method;
274 }
275 }
276 return $ar;
277 }
278
279 function Start()
280 {
281 $this->test_percent = 100; // by default
282
283 ob_start();
284 try
285 {
286 if ($this->fix_mode && (!isset($this->arTestVars['start_function']) || $this->arTestVars['start_function'] != $this->function))
287 {
288 // dummy hit to display zero progress
289 $this->arTestVars['start_function'] = $this->function;
290 $this->test_percent = 0;
291 $this->result = true;
292 }
293 else
294 {
295 $this->result = call_user_func([$this, $this->function]);
296 }
297 }
298 catch (Exception $e)
299 {
300 $this->Result(null, GetMessage("MAIN_SC_TEST_IS_INCORRECT"));
301 echo $e->getMessage();
302 }
303 $this->strError = ob_get_clean();
304
305 if (!$this->strResult)
306 {
307 $this->Result($this->result);
308 }
309
310 if (!$this->fix_mode)
311 {
312 // write to log
313 if (@$this->OpenLog())
314 {
315 $text = date('Y-M-d H:i:s') . ' ' . $this->strCurrentTestName . ' (' . $this->function . "): " . $this->LogResult . "\n";
316 if ($this->test_percent < 100)
317 {
318 $text .= $this->test_percent . '% done' . "\n";
319 }
320
321 if ($this->strError)
322 {
323 $text .= str_replace('<br>', "\n", $this->strError) . "\n";
324 }
325
326 if ($this->test_percent >= 100) // test finished
327 {
328 $text .= preg_replace('#<[^<>]+>#', '', $this->strResult) . "\n";
329 }
330
331 $text = htmlspecialchars_decode($text);
332
333 fwrite($this->LogResourse, $text);
334 }
335 }
336
337 $this->last_function = $this->function;
338 $this->percent = floor(($this->step + $this->test_percent / 100) / count($this->arTest) * 100);
339
340 if ($this->test_percent >= 100) // test finished
341 {
342 if ($this->step + 1 < count($this->arTest))
343 {
344 $this->step++;
345 $this->test_percent = 0;
346 $this->arTestVars['last_value'] = '';
347 $this->function = key($this->arTest[$this->step]);
348 $this->strNextTestName = current($this->arTest[$this->step]);
349 }
350 else // finish
351 {
352 if (!$this->fix_mode) // if we have a kernel
353 {
354 COption::SetOptionString('main', 'site_checker_success', $this->arTestVars['site_checker_success'] ?? '');
355 if (isset($this->arTestVars['site_checker_success']) && $this->arTestVars['site_checker_success'] == 'Y')
356 {
357 CAdminNotify::DeleteByTag('SITE_CHECKER');
358 }
359 }
360 }
361 }
362 elseif ($this->result === true)
363 {
364 $this->strResult = '';
365 } // in case of temporary result on this step
366
367 if ($this->result === false)
368 {
369 $this->arTestVars['site_checker_success'] = 'N';
370 }
371 }
372
373 function Result($result, $text = '')
374 {
375 if ($result === true)
376 {
377 $this->LogResult = 'Ok';
378 }
379 elseif ($result === null)
380 {
381 $this->LogResult = 'Warning';
382 }
383 else
384 {
385 $this->LogResult = 'Fail';
386 }
387
388 if ($result === false)
389 {
390 $text = GetMessage('SC_ERROR0') . ' ' . ($text ?: GetMessage('SC_ERROR1'));
391 }
392 elseif ($result === null)
393 {
394 $text = GetMessage("MAIN_SC_SOME_WARNING") . '. ' . ($text ?: GetMessage('SC_WARN'));
395 }
396 else
397 {
398 $text = $text ?: GetMessage('SC_TEST_SUCCESS');
399 }
400
401 $this->strResult = $text;
402 return $result;
403 }
404
405 function OpenLog()
406 {
407 $continue = $this->step > 0;
408 if (!$this->LogResourse = fopen($_SERVER['DOCUMENT_ROOT'] . $this->LogFile, $continue ? 'ab' : 'wb'))
409 {
410 $this->arTestVars['site_checker_success'] = 'N';
411 }
412 return $this->LogResourse;
413 }
414
415 function ConnectToHost($host = false, $port = false, $ssl = false)
416 {
417 if (!$host)
418 {
419 if (!empty($this->arTestVars['check_socket_fail']))
420 {
421 return $this->Result(null, GetMessage('SC_SOCK_NA'));
422 }
423
426 $ssl = $this->ssl ? 'ssl://' : '';
427 }
428
429 echo "Connection to $ssl$host:$port ";
430 $res = false;
431 try
432 {
433 $res = fsockopen($ssl . $host, $port, $errno, $errstr, 5);
434 }
435 catch (Exception)
436 {
437 }
438
439 if (!$res)
440 {
441 echo "Fail\n";
442 echo "Socket error [$errno]: $errstr" . "\n";
443 return $this->Result(false);
444 }
445 echo "Success\n";
446
447 return $res;
448 }
449
450 function Unformat($str)
451 {
452 $str = strtolower($str);
453 $res = intval($str);
454 $suffix = substr($str, -1);
455 if ($suffix == "k")
456 {
457 $res *= 1024;
458 }
459 elseif ($suffix == "m")
460 {
461 $res *= 1048576;
462 }
463 elseif ($suffix == "g")
464 {
465 $res *= 1048576 * 1024;
466 }
467 elseif ($suffix == "b")
468 {
469 $res = self::Unformat(substr($str, 0, -1));
470 }
471 return $res;
472 }
473
474 function TableFieldCanBeAltered($f, $f_tmp)
475 {
476 if ($f['Type'] == str_replace(['long', 'medium'], '', $f_tmp['Type']) || $this->force_repair)
477 {
478 return true;
479 }
480 if (
481 preg_match('#^([a-z]+)\‍(([0-9]+)\‍)(.*)$#i', $f['Type'], $regs)
482 &&
483 preg_match('#^([a-z]+)\‍(([0-9]+)\‍)(.*)$#i', $f_tmp['Type'], $regs_tmp)
484 &&
485 str_replace('varchar', 'char', strtolower($regs[1])) == str_replace('varchar', 'char', strtolower($regs_tmp[1]))
486 &&
487 $regs[2] <= $regs_tmp[2]
488 &&
489 $regs[3] == $regs_tmp[3] // signed || unsigned
490 )
491 {
492 return true;
493 }
494 return false;
495 }
496
497 ###### TESTS #######
498 # {
499 #
500
502 {
503 $arMods = [
504 'fsockopen' => GetMessage("SC_SOCKET_F"),
505 'xml_parser_create' => GetMessage("SC_MOD_XML"),
506 'imagettftext' => "Free Type Text",
507 'gzcompress' => "Zlib",
508 'imagecreatetruecolor' => GetMessage("SC_MOD_GD"),
509 'imagecreatefromjpeg' => GetMessage("SC_MOD_GD_JPEG"),
510 'hash' => 'Hash',
511 'highlight_file' => 'PHP Syntax Highlight',
512 ];
513
514 $strError = '';
515 foreach ($arMods as $func => $desc)
516 {
517 if (!function_exists($func))
518 {
519 $strError .= $desc . "<br>";
520 }
521 }
522
523 if (!function_exists('openssl_encrypt'))
524 {
525 $strError .= GetMessage("MAIN_SC_MCRYPT") . ' OpenSSL';
526 }
527
528 if (!function_exists('mb_substr'))
529 {
530 $strError .= GetMessage("SC_MOD_MBSTRING") . "<br>";
531 }
532
533 if (!in_array('ssl', stream_get_transports()))
534 {
535 $strError .= GetMessage('ERR_NO_SSL') . '<br>';
536 }
537
538 if ($strError)
539 {
540 return $this->Result(false, GetMessage('ERR_NO_MODS') . "<br>" . $strError);
541 }
542
543 if (IsModuleInstalled('intranet'))
544 {
545 if (!class_exists('DOMDocument') || !class_exists('ZipArchive'))
546 {
547 return $this->Result(null, GetMessage('ERR_NO_MODS_DOC_GENERATOR'));
548 }
549 }
550 return $this->Result(true, GetMessage("MAIN_SC_ALL_MODULES"));
551 }
552
554 {
555 $strError = '';
556 if (version_compare($v = phpversion(), self::MIN_PHP_VER, '<'))
557 {
558 $strError = GetMessage('SC_VER_ERR', ['#CUR#' => $v, '#REQ#' => self::MIN_PHP_VER]) . "<br>";
559 }
560
561 $arRequiredParams = [
562 'safe_mode' => 0,
563 'file_uploads' => 1,
564 'session.auto_start' => 0,
565 'magic_quotes_runtime' => 0,
566 'magic_quotes_sybase' => 0,
567 'magic_quotes_gpc' => 0,
568 'arg_separator.output' => '&',
569 'register_globals' => 0,
570 'zend.multibyte' => 0,
571 ];
572
573 if (extension_loaded('xcache'))
574 {
575 $arRequiredParams['xcache.cacher'] = 0;
576 $arRequiredParams['xcache.stat'] = 1;
577 }
578
579 foreach ($arRequiredParams as $param => $val)
580 {
581 $cur = ini_get($param);
582 if (strtolower($cur) == 'on')
583 {
584 $cur = 1;
585 }
586 elseif (strtolower($cur) == 'off')
587 {
588 $cur = 0;
589 }
590
591 if ($cur != $val)
592 {
593 $strError .= GetMessage('SC_ERR_PHP_PARAM', ['#PARAM#' => $param, '#CUR#' => $cur ? htmlspecialcharsbx($cur) : 'off', '#REQ#' => $val ? 'on' : 'off']) . "<br>";
594 }
595 }
596
597 $param = 'opcache.revalidate_freq';
598 if (($cur = ini_get($param)) <> 0)
599 {
600 $strError .= GetMessage('SC_ERR_PHP_PARAM', ['#PARAM#' => $param, '#CUR#' => htmlspecialcharsbx($cur), '#REQ#' => '0']) . "<br>";
601 }
602
603 $param = 'default_socket_timeout';
604 if (($cur = ini_get($param)) < 60)
605 {
606 $strError .= GetMessage('SC_ERR_PHP_PARAM', ['#PARAM#' => $param, '#CUR#' => htmlspecialcharsbx($cur), '#REQ#' => '60']) . "<br>";
607 }
608
609 if (($m = ini_get('max_input_vars')) && $m < 10000)
610 {
611 $strError .= GetMessage('ERR_MAX_INPUT_VARS', ['#MIN#' => 10000, '#CURRENT#' => $m]) . "<br>";
612 }
613
614 if (IsModuleInstalled('intranet'))
615 {
616 $vm = new BitrixVm();
617 $vmVer = $vm->getVersion();
618 if (!$vmVer)
619 {
620 $strError .= GetMessage('ERR_NO_VM') . "<br>";
621 }
622 else
623 {
624 $vmAvailableVer = $vm->getAvailableVersion();
625 if (version_compare($vmVer, $vmAvailableVer, '<'))
626 {
627 $strError .= GetMessage('ERR_OLD_VM', ['#CURRENT#' => $vmVer, '#LAST_VERSION#' => $vmAvailableVer]) . "<br>";
628 }
629 }
630 }
631
632 // check_divider
633 $locale_info = localeconv();
634 $delimiter = $locale_info['decimal_point'];
635 if ($delimiter != '.')
636 {
637 $strError .= GetMessage('SC_DELIMITER_ERR', ['#VAL#' => $delimiter]) . '<br>';
638 }
639
640 // check_precision
641 if (1234567891 != (string)doubleval(1234567891))
642 {
643 $strError .= GetMessage("MAIN_SC_ERROR_PRECISION") . '<br>';
644 }
645
646 // check_suhosin
647 if (in_array('suhosin', get_loaded_extensions()) && !ini_get('suhosin.simulation'))
648 {
649 $strError .= GetMessage('SC_WARN_SUHOSIN', ['#VAL#' => ini_get('suhosin.simulation') ? 1 : 0]) . '<br>';
650 }
651
652 // check_backtrack_limit
653 $param = 'pcre.backtrack_limit';
654 $cur = self::Unformat(ini_get($param));
655 ini_set($param, $cur + 1);
656 $new = ini_get($param);
657 if ($new != $cur + 1)
658 {
659 $strError .= GetMessage("MAIN_SC_CANT_CHANGE") . '<br>';
660 }
661
662 if ($strError)
663 {
664 return $this->Result(false, $strError);
665 }
666 return $this->Result(true, GetMessage("MAIN_SC_CORRECT_SETTINGS"));
667 }
668
670 {
671 $strError = '';
672 [$host,] = explode(':', $_SERVER['HTTP_HOST'] ?? '');
673 if ($host != 'localhost' && !preg_match('#^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$#', $host))
674 {
675 if (!preg_match('#^[a-z0-9\-.]{1,192}\.(xn--)?[a-z0-9]{2,63}$#i', $host))
676 {
677 $strError .= GetMessage("SC_TEST_DOMAIN_VALID", ['#VAL#' => htmlspecialcharsbx($_SERVER['HTTP_HOST'] ?? '')]) . "<br>";
678 }
679 }
680 if ($strError)
681 {
682 return $this->Result(false, $strError);
683 }
684 return $this->Result(true, GetMessage("MAIN_IS_CORRECT"));
685 }
686
687 function check_mail($big = false)
688 {
690 $body = "Test message. Delete it.{$eol}";
691 if ($big)
692 {
693 $body = str_repeat($body, 8000);
694 }
695
696 $startTime = microtime(true);
697 if ($big)
698 {
699 $val = mail("hosting_test@bitrixsoft.com", "Bitrix site checker" . $eol . "\tmultiline subject", $body, 'BCC: noreply@bitrixsoft.com');
700 }
701 else
702 {
703 $val = mail("hosting_test@bitrixsoft.com", "Bitrix site checker", $body);
704 }
705 $endTime = microtime(true);
706 $time = round($endTime - $startTime, 2);
707 if ($val)
708 {
709 if ($time > 1)
710 {
711 return $this->Result($this->arTestVars['check_bx_crontab'] ? null : false, GetMessage('SC_SENT') . ' ' . $time . ' ' . GetMessage('SC_SEC'));
712 }
713 }
714 else
715 {
716 return false;
717 }
718
719 return true;
720 }
721
722 function check_mail_big()
723 {
724 return $this->check_mail(true);
725 }
726
728 {
729 global $DB, $CACHE_MANAGER;
730
731 $res = $DB->Query("SELECT COUNT(1) AS A FROM b_event WHERE SUCCESS_EXEC = 'N'");
732 $f = $res->Fetch();
733 if ($f['A'] > 0)
734 {
735 $info = defined('BX_CRONTAB_SUPPORT') && BX_CRONTAB_SUPPORT ? '<br> ' . GetMessage('SC_CRON_WARN') : '';
736 if (CACHED_b_event !== false && $CACHE_MANAGER->Read(CACHED_b_event, "events"))
737 {
738 $info .= "<br> " . GetMessage('SC_CACHED_EVENT_WARN');
739 }
740 return $this->Result(false, GetMessage('SC_T_MAIL_B_EVENT_ERR') . ' ' . $f['A'] . $info);
741 }
742 return true;
743 }
744
746 {
747 if (!CModule::IncludeModule('mail'))
748 {
749 return $this->Result(null, GetMessage("MAIN_SC_MAIL_IS_NOT_INSTALLED"));
750 }
751 $rs = CMailBox::GetList([], ['SERVER_TYPE' => 'imap']);
752 if ($rs->Fetch())
753 {
754 return true;
755 }
756 return $this->Result(null, GetMessage("MAIN_SC_MAIL_INTEGRATION"));
757 }
758
759 function check_socnet()
760 {
761 if (!CModule::IncludeModule('socialservices'))
762 {
763 return $this->Result(null, GetMessage("MAIN_SC_NO_SOCIAL_MODULE"));
764 }
766 $arActiveSocServ = $oAuthManager->GetActiveAuthServices([]);
767 if (!empty($arActiveSocServ))
768 {
769 if (is_array($arActiveSocServ['Bitrix24Net']))
770 {
771 return true;
772 }
773 return $this->Result(null, GetMessage("MAIN_SC_NO_SOCIAL_SERVICES_24NET"));
774 }
775 return $this->Result(null, GetMessage("MAIN_SC_NO_SOCIAL_SERVICES"));
776 }
777
778 function check_rest()
779 {
780 if (!CModule::IncludeModule('rest'))
781 {
782 return $this->Result(null, GetMessage("MAIN_SC_NO_REST_MODULE"));
783 }
784 return true;
785 }
786
788 {
790 'select' => ['LID', 'NAME', 'SERVER_NAME'],
791 'order' => ['DEF' => 'DESC', 'SORT' => 'ASC'],
792 ])->fetch();
793
794 $domain = $site['SERVER_NAME'] ?: COption::getOptionString('main', 'server_name', '');
795
796 if (preg_match('/^(?<domain>.+):(?<port>\d+)$/', $domain, $matches))
797 {
798 $domain = $matches['domain'];
799 }
800 if (!getmxrr($domain, $mxhosts) || !count($mxhosts))
801 {
802 return $this->Result(null, GetMessage('SC_ERR_DNS', ['#DOMAIN#' => $domain]));
803 }
804
805 $region = Application::getInstance()->getLicense()->getRegion();
806
807 if (in_array($region, ['ru', 'by', 'kz']))
808 {
809 $host = "mail-001.bitrix24.ru";
810 }
811 else
812 {
813 $host = "mail-us.bitrix24.com";
814 }
815
816 foreach ($mxhosts as $mx)
817 {
818 if ($mx != $host)
819 {
820 print_r($mxhosts);
821 return $this->Result(null, GetMessage('SC_ERR_DNS_WRONG', ['#DOMAIN#' => $mx]));
822 }
823 }
824
825 if (!$res = $this->ConnectToHost($host, 25))
826 {
827 return $this->Result(null, GetMessage('SC_ERR_CONNECT_MAIL001'));
828 }
829
830 echo fgets($res);
831 fwrite($res, "HELO " . $domain . "\r\n");
832 echo fgets($res);
833 fwrite($res, "MAIL FROM: sitecheckerfrom@" . $domain . "\r\n");
834 echo fgets($res);
835 fwrite($res, "RCPT TO: rplsitecheckerto@" . $domain . "\r\n");
836 echo fgets($res);
837 fwrite($res, "DATA\r\n");
838 echo fgets($res);
839 fwrite($res,
840 "From: sitecheckerfrom@" . $domain . "\r\n" .
841 "To: rplsitecheckerto@" . $domain . "\r\n" .
842 "Subject: Site checker mail test\r\n" .
843 "Content-type: text/plain\r\n" .
844 "MIME-Version: 1.0\r\n" .
845 "\r\n" .
846 ".\r\n");
847 echo($str = fgets($res));
848 fclose($res);
849 if (preg_match('#\‍(Bad Request 400\‍)#i', $str))
850 {
851 echo "Success\n";
852 return true;
853 }
854 return $this->Result(null, GetMessage('SC_ERR_TEST_MAIL_PUSH', ['#DOMAIN#' => $domain]));
855 }
856
857 function check_socket()
858 {
859 $strRequest = "GET " . "/bitrix/admin/site_checker.php?test_type=socket_test&unique_id=" . checker_get_unique_id() . " HTTP/1.1\r\n";
860 $strRequest .= "Host: " . $this->host . "\r\n";
861 $strRequest .= "\r\n";
862
863 $retVal = false;
864
865 if ($res = $this->ConnectToHost())
866 {
867 $retVal = IsHttpResponseSuccess($res, $strRequest);
868 }
869
870 if (!$retVal)
871 {
872 $this->arTestVars['check_socket_fail'] = 1;
873 }
874 return $retVal;
875 }
876
878 {
879 $strRequest = "GET " . "/bitrix/admin/site_checker.php?test_type=compression&unique_id=" . checker_get_unique_id() . " HTTP/1.1\r\n";
880 $strRequest .= "Host: " . $this->host . "\r\n";
881 $strRequest .= "Accept-Encoding: gzip, deflate\r\n";
882 $strRequest .= "\r\n";
883
884 if (!$res = $this->ConnectToHost())
885 {
886 return false;
887 }
888
889 $strRes = GetHttpResponse($res, $strRequest, $strHeaders);
890
891 if (preg_match('#gzip|deflate#mi', $strHeaders) && strlen($strRes) < 64 * 1024) // comression not supported by server
892 {
893 return $this->Result(true, GetMessage("MAIN_SC_ENABLED_MOD"));
894 }
895 else
896 {
897 return $this->Result(false, GetMessage("MAIN_SC_COMP_DISABLED_MOD"));
898 }
899 }
900
902 {
903 if (!file_exists($this->cafile) || filesize($this->cafile) == 0)
904 {
905 return $this->Result(null, GetMessage("MAIN_SC_TEST_SSL1"));
906 }
907
908 if (!$context = stream_context_create(
909 [
910 'ssl' => [
911 'verify_peer' => true,
912 'allow_self_signed' => false,
913 'cafile' => $this->cafile,
914 ],
915 ]
916 ))
917 {
918 return false;
919 }
920
921 echo "Connection to ssl://{$this->host}:443 (certificate check enabled) ";
922 if ($res = stream_socket_client('ssl://' . $this->host . ':443', $errno, $errstr, 10, STREAM_CLIENT_CONNECT, $context))
923 {
924 echo "Success\n";
925 fclose($res);
926 return true;
927 }
928 echo "Fail\n";
929
930 if (!$context = stream_context_create(
931 [
932 'ssl' => [
933 'verify_peer' => false,
934 'allow_self_signed' => true,
935 'cafile' => $this->cafile,
936 ],
937 ]
938 ))
939 {
940 return false;
941 }
942
943 echo "Connection to ssl://{$this->host}:443 ";
944 if ($res = stream_socket_client('ssl://' . $this->host . ':443', $errno, $errstr, 10, STREAM_CLIENT_CONNECT, $context))
945 {
946 echo "Success\n";
947 fclose($res);
948 return $this->Result(null, GetMessage("MAIN_SC_SSL_NOT_VALID"));
949 }
950 echo "Fail\n";
951 return $this->Result(null, GetMessage("MAIN_SC_NO_CONNECTTO", ['#HOST#' => 'https://' . $this->host]));
952 }
953
954 function check_ad()
955 {
956 if (!CModule::IncludeModule('ldap'))
957 {
958 return $this->Result(null, GetMessage("MAIN_SC_NO_LDAP_MODULE"));
959 }
961 if (!$rs->Fetch())
962 {
963 return $this->Result(null, GetMessage("MAIN_SC_NO_LDAP_INTEGRATION"));
964 }
965 return true;
966 }
967
968 function check_ntlm()
969 {
970 if (!CModule::IncludeModule('ldap'))
971 {
972 return $this->Result(null, GetMessage("MAIN_SC_NO_LDAP_MODULE"));
973 }
974 if (COption::GetOptionString('ldap', 'use_ntlm', 'N') != 'Y')
975 {
976 return $this->Result(null, GetMessage("MAIN_SC_OPTION_SWITCHED_OFF"));
977 }
978 if (COption::GetOptionString('ldap', 'bitrixvm_auth_support', 'N') == 'Y')
979 {
980 return true;
981 }
982 if (($ntlm_varname = COption::GetOptionString('ldap', 'ntlm_varname', 'REMOTE_USER')) && ($user = trim($_SERVER[$ntlm_varname])))
983 {
984 return $this->Result(true, GetMessage("MAIN_SC_NTLM_SUCCESS") . $user);
985 }
986 return $this->Result(null, GetMessage("MAIN_SC_NO_NTLM"));
987 }
988
989 function check_ca_file()
990 {
991 if (file_exists($this->cafile))
992 {
993 unlink($this->cafile);
994 }
995 CheckDirPath($this->cafile);
996
997 $region = Application::getInstance()->getLicense()->getRegion();
998
999 if (in_array($region, ['ru', 'by', 'kz']))
1000 {
1001 $url = 'https://www.1c-bitrix.ru/upload/lib/cafile.pem';
1002 }
1003 else
1004 {
1005 $url = 'https://www.bitrixsoft.com/upload/lib/cafile.pem';
1006 }
1007
1008 $http = new \Bitrix\Main\Web\HttpClient([
1009 "socketTimeout" => 5,
1010 "streamTimeout" => 5,
1011 ]);
1012 if ($http->download($url, $this->cafile) && is_file($this->cafile) && filesize($this->cafile) > 0)
1013 {
1014 return true;
1015 }
1016
1017 return $this->Result(null, GetMessage("MAIN_SC_NO_ACCESS") . '&quot;');
1018 }
1019
1020 function check_dbconn()
1021 {
1022 $strRequest = "GET " . "/bitrix/admin/site_checker.php?test_type=dbconn_test&unique_id=" . checker_get_unique_id() . " HTTP/1.1\r\n";
1023 $strRequest .= "Host: " . $this->host . "\r\n";
1024 $strRequest .= "\r\n";
1025
1026 $retVal = false;
1027 $file = '';
1028 if (IsModuleInstalled('security'))
1029 {
1030 $file = COption::GetOptionString("security", "ipcheck_disable_file", "");
1031 COption::SetOptionString("security", "ipcheck_disable_file", $this->LogFile);
1032 }
1033 if ($res = $this->ConnectToHost())
1034 {
1035 $retVal = IsHttpResponseSuccess($res, $strRequest);
1036 }
1037 if (IsModuleInstalled('security'))
1038 {
1039 COption::SetOptionString("security", "ipcheck_disable_file", $file);
1040 }
1041 return $retVal;
1042 }
1043
1044 function check_upload($big = false, $raw = false)
1045 {
1046 if (($sp = ini_get("upload_tmp_dir")))
1047 {
1048 if (!file_exists($sp))
1049 {
1050 return $this->Result(false, GetMessage('SC_NO_TMP_FOLDER') . ' <i>(' . htmlspecialcharsbx($sp) . ')</i>');
1051 }
1052 elseif (!is_writable($sp))
1053 {
1054 return $this->Result(false, GetMessage('SC_TMP_FOLDER_PERMS') . ' <i>(' . htmlspecialcharsbx($sp) . ')</i>');
1055 }
1056 }
1057
1058 if (defined('BX_TEMPORARY_FILES_DIRECTORY'))
1059 {
1060 $sp = BX_TEMPORARY_FILES_DIRECTORY;
1061 if (!file_exists($sp))
1062 {
1063 return $this->Result(false, GetMessage('SC_NO_TMP_FOLDER') . ' <i>(BX_TEMPORARY_FILES_DIRECTORY: ' . htmlspecialcharsbx($sp) . ')</i>');
1064 }
1065 elseif (!is_writable($sp))
1066 {
1067 return $this->Result(false, GetMessage('SC_TMP_FOLDER_PERMS') . ' <i>(BX_TEMPORARY_FILES_DIRECTORY: ' . htmlspecialcharsbx($sp) . ')</i>');
1068 }
1069 }
1070
1071 $binaryData = '';
1072 for ($i = 40; $i < 240; $i++)
1073 {
1074 $binaryData .= chr($i);
1075 }
1076 if ($big)
1077 {
1078 $binaryData = str_repeat($binaryData, 21000);
1079 }
1080
1081 if ($raw)
1082 {
1083 $POST = $binaryData;
1084 }
1085 else
1086 {
1087 $boundary = '--------' . md5(checker_get_unique_id());
1088
1089 $POST = "--$boundary\r\n";
1090 $POST .= 'Content-Disposition: form-data; name="test_file"; filename="site_checker.bin"' . "\r\n";
1091 $POST .= 'Content-Type: image/gif' . "\r\n";
1092 $POST .= "\r\n";
1093 $POST .= $binaryData . "\r\n";
1094 $POST .= "--$boundary\r\n";
1095 }
1096
1097 $strRequest = "POST " . "/bitrix/admin/site_checker.php?test_type=upload_test&unique_id=" . checker_get_unique_id() . "&big=" . ($big ? 1 : 0) . "&raw=" . ($raw ? 1 : 0) . " HTTP/1.1\r\n";
1098 $strRequest .= "Host: " . $this->host . "\r\n";
1099 if (!$raw)
1100 {
1101 $strRequest .= "Content-Type: multipart/form-data; boundary=$boundary\r\n";
1102 }
1103 $strRequest .= "Content-Length: " . strlen($POST) . "\r\n";
1104 $strRequest .= "\r\n";
1105 $strRequest .= $POST;
1106
1107 if ($res = $this->ConnectToHost())
1108 {
1109 return IsHttpResponseSuccess($res, $strRequest);
1110 }
1111 return false;
1112 }
1113
1115 {
1116 return $this->check_upload(true);
1117 }
1118
1120 {
1121 return $this->check_upload(false, true);
1122 }
1123
1124 function check_post()
1125 {
1126 $POST = '';
1127 for ($i = 0; $i < 201; $i++)
1128 {
1129 $POST .= 'i' . $i . '=' . md5($i) . '&';
1130 }
1131
1132 $strRequest = "POST " . "/bitrix/admin/site_checker.php?test_type=post_test&unique_id=" . checker_get_unique_id() . " HTTP/1.1\r\n";
1133 $strRequest .= "Host: " . $this->host . "\r\n";
1134 $strRequest .= "Content-Length: " . strlen($POST) . "\r\n";
1135 $strRequest .= "Content-Type: application/x-www-form-urlencoded\r\n";
1136
1137 $strRequest .= "\r\n";
1138 $strRequest .= $POST;
1139
1140 if ($res = $this->ConnectToHost())
1141 {
1142 return IsHttpResponseSuccess($res, $strRequest);
1143 }
1144 return false;
1145 }
1146
1148 {
1149 $total_steps = 5;
1150
1151 if (!$this->arTestVars['last_value'])
1152 {
1153 $last_success = 0;
1154 $max = 16;
1155 $step = 1;
1156 }
1157 else
1158 {
1159 if (!CheckSerializedData($this->arTestVars['last_value']))
1160 {
1161 return false;
1162 }
1163 [$last_success, $max, $step] = unserialize($this->arTestVars['last_value'], ['allowed_classes' => false]);
1164 }
1165
1166 $strRequest = "GET " . "/bitrix/admin/site_checker.php?test_type=memory_test&unique_id=" . checker_get_unique_id() . "&max=" . ($max - 1) . " HTTP/1.1\r\n";
1167 $strRequest .= "Host: " . $this->host . "\r\n";
1168 $strRequest .= "\r\n";
1169
1170 if (!$res = $this->ConnectToHost())
1171 {
1172 return false;
1173 }
1174
1175 if (IsHttpResponseSuccess($res, $strRequest))
1176 {
1177 $last_success = $max;
1178 $max *= 2;
1179 }
1180 else
1181 {
1182 $max = floor(($last_success + $max) / 2);
1183 }
1184
1185 if ($max < 16)
1186 {
1187 return false;
1188 }
1189
1190 if ($step < $total_steps)
1191 {
1192 $this->test_percent = floor(100 / $total_steps * $step);
1193 $step++;
1194 $this->arTestVars['last_value'] = serialize([$last_success, $max, $step]);
1195 return true;
1196 }
1197
1198 $ok = false;
1199 $res = GetMessage('SC_NOT_LESS', ['#VAL#' => $last_success]);
1200 $last_success = (int)$last_success;
1201 if ($last_success > 32)
1202 {
1203 $ok = true;
1204 $cur = \Bitrix\Main\Config\Ini::getInt('memory_limit');
1205 if ($cur > 0 && $cur < $last_success * 1024 * 1024)
1206 {
1207 $res .= '<br> ' . GetMessage('SC_MEMORY_CHANGED', ['#VAL0#' => ini_get('memory_limit'), '#VAL1#' => '512M']);
1208 $ok = null;
1209 }
1210 }
1211 return $this->Result($ok, $res);
1212 }
1213
1214 function check_session()
1215 {
1216 if (!$this->arTestVars['last_value'])
1217 {
1218 $_SESSION['CHECKER_CHECK_SESSION'] = 'SUCCESS';
1219 $this->test_percent = 50;
1220 $this->arTestVars['last_value'] = 'Y';
1221 }
1222 else
1223 {
1224 if ($_SESSION['CHECKER_CHECK_SESSION'] != 'SUCCESS')
1225 {
1226 return false;
1227 }
1228 unset($_SESSION['CHECKER_CHECK_SESSION']);
1229 }
1230 return true;
1231 }
1232
1234 {
1235 $strRequest = "GET " . "/bitrix/admin/site_checker.php?test_type=session_test&unique_id=" . checker_get_unique_id() . " HTTP/1.1\r\n";
1236 $strRequest .= "Host: " . $this->host . "\r\n";
1237
1238 if ($this->arTestVars['last_value']) // second step: put session id
1239 {
1240 $strRequest .= "Cookie: " . $this->arTestVars['last_value'] . "\r\n";
1241 }
1242
1243 $strRequest .= "\r\n";
1244
1245 if (!$res = $this->ConnectToHost())
1246 {
1247 return false;
1248 }
1249
1250 if (!$this->arTestVars['last_value']) // first step: read session id
1251 {
1252 $strRes = GetHttpResponse($res, $strRequest, $strHeaders);
1253 if (!preg_match('#Set-Cookie: (' . session_name() . '=[a-z0-9\-_]+?);#i', $strHeaders, $regs))
1254 {
1255 PrintHTTP($strRequest, $strHeaders, $strRes);
1256 return false;
1257 }
1258
1259 $this->arTestVars['last_value'] = $regs[1];
1260 $this->test_percent = 50;
1261 return true;
1262 }
1263 else
1264 {
1265 return IsHttpResponseSuccess($res, $strRequest);
1266 }
1267 }
1268
1270 {
1271 $file = $_SERVER['DOCUMENT_ROOT'] . '/bitrix/.settings.php';
1272
1273 if ($this->fix_mode)
1274 {
1275 if (!file_exists($file))
1276 {
1278 Application::resetAccelerator();
1279 }
1280 return $this->Result(file_exists($file));
1281 }
1282
1283 if (!file_exists($file))
1284 {
1285 $this->arTestVars['check_mbstring_fail'] = true;
1286 $mode = 4;
1287 $link = ' <a href="javascript:show_popup(\'' . GetMessageJS('SC_FIX_MBSTRING') . '\', \'?fix_mode=' . $mode . '\', \'' . GetMessageJS('SC_FIX_MBSTRING_CONFIRM') . '\')">' . GetMessage('SC_FIX') . '</a>';
1288 return $this->Result(false, GetMessage('SC_ERR_NO_SETTINGS') . $link);
1289 }
1290
1291 $encoding = strtolower(ini_get('mbstring.internal_encoding'));
1292 $default = strtolower(ini_get('default_charset'));
1293
1294 if ($default == "")
1295 {
1296 return $this->Result(false, GetMessage("MAIN_SC_DEFAULT_CHARSET"));
1297 }
1298
1299 if ($encoding <> '' && $encoding <> $default)
1300 {
1301 return $this->Result(false, GetMessage("MAIN_SC_ENC_EQUAL"));
1302 }
1303
1304 if (ini_get('mbstring.func_overload') > 0)
1305 {
1306 //should be non-existent
1307 return $this->Result(false, GetMessage("MAIN_SC_FUNC_OVERLOAD"));
1308 }
1309
1310 $retVal = true;
1311 $bUtf = false;
1312
1313 $rs = CSite::GetList('', '', ['ACTIVE' => 'Y']);
1314 while ($f = $rs->Fetch())
1315 {
1316 if (str_contains(strtolower($f['CHARSET']), 'utf'))
1317 {
1318 $bUtf = true;
1319 break;
1320 }
1321 }
1322
1323 if ($bUtf)
1324 {
1325 $text = GetMessage('SC_MB_UTF');
1326
1327 if ($default <> "utf-8")
1328 {
1329 $retVal = false;
1330 $text .= '<br>' . GetMessage("MAIN_SC_ENC_UTF");
1331 $this->arTestVars['check_mbstring_fail'] = true;
1332 }
1333 }
1334 else
1335 {
1336 $text = GetMessage('SC_MB_NOT_UTF');
1337 }
1338
1339 if ($retVal)
1340 {
1341 $retVal = (strlen("\xd0\xa2") == 2);
1342 if (!$retVal)
1343 {
1344 $text = GetMessage('SC_STRLEN_FAIL_PHP56');
1345 }
1346 }
1347
1348 return $this->Result($retVal, ($retVal ? GetMessage("MAIN_SC_CORRECT") . '. ' : '') . $text);
1349 }
1350
1351 function check_http_auth()
1352 {
1353 $strRequest = "GET " . "/bitrix/admin/site_checker.php?test_type=auth_test&unique_id=" . checker_get_unique_id() . " HTTP/1.1\r\n";
1354 $strRequest .= "Host: " . $this->host . "\r\n";
1355 $strRequest .= "Authorization: Basic dGVzdF91c2VyOnRlc3RfcGFzc3dvcmQ=\r\n";
1356 $strRequest .= "\r\n";
1357
1358 if ($res = $this->ConnectToHost())
1359 {
1360 return IsHttpResponseSuccess($res, $strRequest);
1361 }
1362 return false;
1363 }
1364
1365 function check_update()
1366 {
1367 $ServerIP = COption::GetOptionString("main", "update_site", "www.1c-bitrix.ru");
1368 $ServerPort = 80;
1369
1370 $proxyAddr = COption::GetOptionString("main", "update_site_proxy_addr", "");
1371 $proxyPort = COption::GetOptionString("main", "update_site_proxy_port", "");
1372 $proxyUserName = COption::GetOptionString("main", "update_site_proxy_user", "");
1373 $proxyPassword = COption::GetOptionString("main", "update_site_proxy_pass", "");
1374
1375 $bUseProxy = !$this->arTestVars['last_value'] && $proxyAddr <> '' && $proxyPort <> '';
1376
1377 if ($bUseProxy)
1378 {
1379 $proxyPort = intval($proxyPort);
1380 if ($proxyPort <= 0)
1381 {
1382 $proxyPort = 80;
1383 }
1384
1385 $requestIP = $proxyAddr;
1386 $requestPort = $proxyPort;
1387 }
1388 else
1389 {
1390 $requestIP = $ServerIP;
1391 $requestPort = $ServerPort;
1392 }
1393
1394 $strRequest = "";
1395 $page = "us_updater_list.php";
1396 if ($bUseProxy)
1397 {
1398 $strRequest .= "POST http://" . $ServerIP . "/bitrix/updates/" . $page . " HTTP/1.0\r\n";
1399 if ($proxyUserName <> '')
1400 {
1401 $strRequest .= "Proxy-Authorization: Basic " . base64_encode($proxyUserName . ":" . $proxyPassword) . "\r\n";
1402 }
1403 }
1404 else
1405 {
1406 $strRequest .= "POST /bitrix/updates/" . $page . " HTTP/1.0\r\n";
1407 }
1408
1409 $strRequest .= "User-Agent: BitrixSMUpdater\r\n";
1410 $strRequest .= "Accept: */*\r\n";
1411 $strRequest .= "Host: " . $ServerIP . "\r\n";
1412 $strRequest .= "Accept-Language: en\r\n";
1413 $strRequest .= "Content-type: application/x-www-form-urlencoded\r\n";
1414 $strRequest .= "Content-length: 7\r\n\r\n";
1415 $strRequest .= "lang=en";
1416 $strRequest .= "\r\n";
1417
1418 $res = false;
1419 try
1420 {
1421 $res = fsockopen($requestIP, $requestPort, $errno, $errstr, 5);
1422 }
1423 catch (Exception $e)
1424 {
1425 echo $e->getMessage() . "\n";
1426 }
1427
1428 if (!$res)
1429 {
1430 if ($bUseProxy)
1431 {
1432 return $this->Result(false, GetMessage('SC_NO_PROXY') . ' (' . $errstr . ')');
1433 }
1434 else
1435 {
1436 return $this->Result(false, GetMessage('SC_UPDATE_ERROR') . ' (' . $errstr . ')');
1437 }
1438 }
1439 else
1440 {
1441 if (\Bitrix\Main\Config\Option::get("updateserverlight", "is_turned_on", "N") === "Y")
1442 {
1443 return true;
1444 }
1445
1446 $strRes = GetHttpResponse($res, $strRequest, $strHeaders);
1447
1448 if ((str_contains($strRes, "EMPTY_LICENSE_KEY"))
1449 || (str_contains($strRes, "LICENSE_KEY_REQUIRED")))
1450 {
1451 return true;
1452 }
1453 else
1454 {
1455 $strRes = mb_strtolower(strip_tags($strRes));
1456 PrintHTTP($strRequest, $strHeaders, $strRes);
1457 if ($bUseProxy)
1458 {
1459 return $this->Result(false, GetMessage('SC_PROXY_ERR_RESP'));
1460 }
1461 else
1462 {
1463 return $this->Result(false, GetMessage('SC_UPDATE_ERR_RESP'));
1464 }
1465 }
1466 }
1467 }
1468
1470 {
1471 if (CModule::IncludeModule('pull'))
1472 {
1473 $text = md5(mt_rand(100000, 999999));
1474 $channelId = md5($text);
1476 if (CPullOptions::GetQueueServerStatus())
1477 {
1478 $isServerShared = CPullOptions::IsServerShared();
1479 if ($isServerShared && !\Bitrix\Pull\SharedServer\Config::isRegistered())
1480 {
1481 $this->arTestVars['push_stream_fail'] = true;
1482 return $this->Result(false, GetMessage("MAIN_SC_PULL_NOT_REGISTERED"));
1483 }
1484 else
1485 {
1486 if (CPullOptions::GetQueueServerVersion() < 4)
1487 {
1488 $this->arTestVars['push_stream_warn'] = true;
1489 return $this->Result(null, GetMessage("MAIN_SC_PULL_UNSUPPORTED_VERSION"));
1490 }
1491 else
1492 {
1493 if (!$ar = parse_url(str_replace('#DOMAIN#', $this->host, \Bitrix\Pull\Config::getPublishUrl($id))))
1494 {
1495 return $this->Result(false, GetMessage("MAIN_SC_PATH_PUB"));
1496 }
1497
1498 $pub_domain = $ar['host'];
1499 $pub_host = ($ar['scheme'] == 'https' ? 'ssl://' : '') . $pub_domain;
1500 $pub = $ar['path'] . '?' . $ar['query'];
1501 $pub_port = $ar['port'];
1502 if (!$pub_port)
1503 {
1504 $pub_port = $ar['scheme'] == 'https' ? 443 : 80;
1505 }
1506
1507 if ($isServerShared)
1508 {
1510 $listenUrl .= "?CHANNEL_ID=" . $id . "&clientId=" . \Bitrix\Pull\SharedServer\Client::getPublicLicenseCode();
1511 }
1512 else
1513 {
1514 $listenUrl = $this->ssl ? CPullOptions::GetListenSecureUrl($id) : CPullOptions::GetListenUrl($id);
1515 }
1516
1517 if (!$ar = parse_url(str_replace('#DOMAIN#', $this->host, $listenUrl)))
1518 {
1519 return $this->Result(false, GetMessage("MAIN_SC_PATH_SUB"));
1520 }
1521
1522 $sub_domain = $ar['host'];
1523 $sub_host = ($ar['scheme'] == 'https' ? 'ssl://' : '') . $sub_domain;
1524 $sub = $ar['path'] . '?' . $ar['query'];
1525 $sub_port = $ar['port'] ?? null;
1526 if (!$sub_port)
1527 {
1528 $sub_port = $ar['scheme'] == 'https' ? 443 : 80;
1529 }
1530 }
1531 }
1532 }
1533 else
1534 {
1535 $this->arTestVars['push_stream_fail'] = true;
1536 return $this->Result(false, GetMessage("MAIN_SC_STREAM_DISABLED_2"));
1537 }
1538 }
1539 else
1540 {
1541 $this->arTestVars['push_stream_fail'] = true;
1542 return $this->Result(false, GetMessage("MAIN_NO_PULL"));
1543 }
1544
1545 $ver = CPullOptions::GetQueueServerVersion();
1546 $bNodeJS = $ver > 2;
1547 echo 'Server version: ' . $ver . ($bNodeJS ? ' (Bitrix Push server)' : ' (nginx-push-stream-module)') . "\n";
1548
1549 $strRequest0 = 'POST ' . $pub . ' HTTP/1.0' . "\r\n" .
1550 'Host: ' . $pub_domain . "\r\n" .
1551 'Content-Length: ' . strlen($text) . "\r\n" .
1552 "\r\n" .
1553 $text . "\r\n";
1554 $strRequest1 = 'GET ' . $sub . ' HTTP/1.0' . "\r\n" .
1555 'If-Modified-Since: ' . date('r', time() - 86400) . "\r\n" .
1556 'Host: ' . $sub_domain . "\r\n\r\n";
1557 $strRequest2 = 'DELETE ' . $pub . ' HTTP/1.0' . "\r\n" .
1558 'Host: ' . $sub_domain . "\r\n\r\n";
1559
1560 if (!$bNodeJS)
1561 {
1562 // POST - to create a channel
1563 if (!$res0 = $this->ConnectToHost($pub_host, $pub_port))
1564 {
1565 $this->arTestVars['push_stream_fail'] = true;
1566 return $this->Result(false, GetMessage("MAIN_SC_NO_PUSH_STREAM_CONNECTION"));
1567 }
1568 fwrite($res0, $strRequest0);
1569 fclose($res0);
1570 }
1571
1572 // GET - connection
1573 if (!$res1 = $this->ConnectToHost($sub_host, $sub_port))
1574 {
1575 $this->arTestVars['push_stream_fail'] = true;
1576 return $this->Result(false, GetMessage("MAIN_SC_NO_SUB_CONNECTION_2"));
1577 }
1578 fwrite($res1, $strRequest1);
1579 sleep(1); // we need some time to create channel
1580
1581 // POST - message
1582 $postResult = CPullChannel::Send($channelId, $text, ['dont_wait_answer' => false]);
1583 if (!$postResult)
1584 {
1585 $this->arTestVars['push_stream_fail'] = true;
1586 return $this->Result(false, GetMessage("MAIN_SC_NO_PUSH_STREAM_CONNECTION"));
1587 }
1588
1589 // GET - message
1590 $strRes1 = fread($res1, 4096);
1591
1592 $retVal = true;
1593 if (!str_contains($strRes1, $text))
1594 {
1595 PrintHTTP($strRequest1, '', $strRes1);
1596 $this->arTestVars['push_stream_fail'] = true;
1597 $retVal = $this->Result(false, GetMessage("MAIN_SC_PUSH_INCORRECT", ['#MODULE#' => $bNodeJS ? 'Bitrix Push server' : 'nginx-push-stream-module']));
1598 }
1599
1600 // DELETE
1601 if (!$res2 = $this->ConnectToHost($pub_host, $pub_port))
1602 {
1603 $this->arTestVars['push_stream_fail'] = true;
1604 return $this->Result(false, GetMessage("MAIN_SC_NO_PUSH_STREAM_CONNECTION_2"));
1605 }
1606 fwrite($res2, $strRequest2);
1607 fclose($res2);
1608
1609 if ($retVal && COption::GetOptionString('main', 'session_expand', 'Y') <> 'N' && (!defined("BX_SKIP_SESSION_EXPAND") || BX_SKIP_SESSION_EXPAND === false))
1610 {
1611 return $this->Result(null, GetMessage('MAIN_SC_WARN_EXPAND_SESSION'));
1612 }
1613
1614 return $retVal;
1615 }
1616
1618 {
1619 if (!empty($this->arTestVars['push_stream_warn']))
1620 {
1621 return $this->Result(null, GetMessage("MAIN_SC_NO_PUSH_STREAM_2"));
1622 }
1623 else
1624 {
1625 if (!empty($this->arTestVars['push_stream_fail']))
1626 {
1627 return $this->Result(false, GetMessage("MAIN_SC_NO_PUSH_STREAM_2"));
1628 }
1629 }
1630 return true;
1631 }
1632
1633 function check_turn()
1634 {
1635 if (!IsModuleInstalled('im') || !IsModuleInstalled('call'))
1636 {
1637 return $this->Result(null, GetMessage("MAIN_SC_NO_IM"));
1638 }
1639
1640 if (!empty($this->arTestVars['push_stream_warn']))
1641 {
1642 return $this->Result(null, GetMessage("MAIN_SC_NO_PUSH_STREAM_VIDEO_2"));
1643 }
1644 else
1645 {
1646 if (!empty($this->arTestVars['push_stream_fail']))
1647 {
1648 return $this->Result(false, GetMessage("MAIN_SC_NO_PUSH_STREAM_VIDEO_2"));
1649 }
1650 }
1651
1652 if (COption::GetOptionString("call", "turn_server_self") == 'Y')
1653 {
1654 $host = COption::GetOptionString("call", "turn_server");
1655 }
1656 else
1657 {
1658 $region = Application::getInstance()->getLicense()->getRegion();
1659
1660 if (in_array($region, ['ru', 'by', 'kz']))
1661 {
1662 $host = "turn.bitrix24.tech";
1663 }
1664 else
1665 {
1666 $host = 'turn.calls.bitrix24.com';
1667 }
1668 }
1669 $port = 3478;
1670
1671 if (!($res = $this->ConnectToHost($host, $port)))
1672 {
1673 $res = $this->ConnectToHost('udp://' . $host, $port);
1674 }
1675
1676 if ($res)
1677 {
1678 fclose($res);
1679 return $this->Result(true, GetMessage("MAIN_SC_AVAIL"));
1680 }
1681 return $this->Result(null, GetMessage("MAIN_SC_NOT_AVAIL"));
1682 }
1683
1685 {
1686 if (!CModule::IncludeModule('pull'))
1687 {
1688 return $this->Result(null, GetMessage("MAIN_NO_PULL_MODULE"));
1689 }
1690 if (!CPullOptions::GetPushStatus())
1691 {
1692 return $this->Result(null, GetMessage("MAIN_NO_OPTION_PULL"));
1693 }
1694
1695 if ($this->arTestVars['check_access_fail'])
1696 {
1697 return $this->Result(false, GetMessage("MAIN_SC_NO_EXTERNAL_ACCESS_MOB"));
1698 }
1699
1700 $region = Application::getInstance()->getLicense()->getRegion();
1701
1702 if (in_array($region, ['ru', 'by', 'kz']))
1703 {
1704 $host = 'cloud-messaging.bitrix24.tech';
1705 }
1706 else
1707 {
1708 $host = 'cloud-messaging.bitrix24.com';
1709 }
1710
1711 $POST = 'Action=SendMessage&MessageBody=batch';
1712
1713 $strRequest = "POST /send/?key=" . md5('key') . " HTTP/1.1\r\n";
1714 $strRequest .= "User-Agent: BitrixCloud SiteChecker\r\n";
1715 $strRequest .= "Host: " . $host . "\r\n";
1716 $strRequest .= "Content-type: application/x-www-form-urlencoded\r\n";
1717 $strRequest .= "Content-length: " . strlen($POST) . "\r\n";
1718 $strRequest .= "\r\n" . $POST . "\r\n";
1719
1720 if (!$res = $this->ConnectToHost('ssl://' . $host, 443))
1721 {
1722 return false;
1723 }
1724
1725 $strRes = mb_strtolower(GetHttpResponse($res, $strRequest, $strHeaders));
1726 if (str_contains($strRes, 'xml version='))
1727 {
1728 return true;
1729 }
1730
1731 PrintHTTP($strRequest, $strHeaders, $strRes);
1732 return $this->Result(false, GetMessage("MAIN_WRONG_ANSWER_PULL"));
1733 }
1734
1736 {
1737 if ($this->arTestVars['check_access_fail'])
1738 {
1739 return $this->Result(null, GetMessage("MAIN_SC_NO_EXTERNAL_ACCESS_"));
1740 }
1741 return true;
1742 }
1743
1745 {
1746 if ($this->arTestVars['check_access_fail'])
1747 {
1748 return $this->Result(false, GetMessage("MAIN_SC_NO_EXTRANET_CONNECT"));
1749 }
1750 return true;
1751 }
1752
1753 function check_webdav()
1754 {
1755 if (!CModule::IncludeModule('webdav') && !CModule::IncludeModule('disk'))
1756 {
1757 return $this->Result(false, GetMessage("MAIN_SC_NO_WEBDAV_MODULE"));
1758 }
1759
1760 if ($this->arTestVars['check_socket_fail'])
1761 {
1762 return $this->Result(null, GetMessage('SC_SOCK_NA'));
1763 }
1764
1765 $allow = [
1766 "PUT" => ["rights" => "U", "min_rights" => "U"],
1767 "LOCK" => ["rights" => "U", "min_rights" => "U"],
1768 "MOVE" => ["rights" => "W", "min_rights" => "U"],
1769 "MKCOL" => ["rights" => "W", "min_rights" => "W"],
1770 "PROPFIND" => ["rights" => "R", "min_rights" => "R"],
1771 ];
1772
1773 foreach ($allow as $method => $ar)
1774 {
1775 $strRequest = $method . " /bitrix/admin/site_checker.php?test_type=webdav_test&method=$method&unique_id=" . checker_get_unique_id() . " HTTP/1.1\r\n";
1776 $strRequest .= "Host: " . $this->host . "\r\n";
1777 $strRequest .= "\r\n";
1778
1779 if (!$res = $this->ConnectToHost())
1780 {
1781 return null;
1782 }
1783 $strRes = GetHttpResponse($res, $strRequest, $strHeaders);
1784 if (trim($strRes) != 'SUCCESS')
1785 {
1786 PrintHTTP($strRequest, $strHeaders, $strRes);
1787 return $this->Result(null, str_replace('#METHOD#', $method, GetMessage("MAIN_SC_METHOD_NOT_SUP")));
1788 }
1789 }
1790 return true;
1791 }
1792
1793 function check_search()
1794 {
1795 if (!CModule::IncludeModule('intranet'))
1796 {
1797 return null;
1798 }
1799
1800 $tmp = $_SERVER['DOCUMENT_ROOT'] . '/bitrix/tmp/success.doc';
1801 if (!CheckDirPath($tmp) || !file_put_contents($tmp, 'SUCCESS'))
1802 {
1803 return $this->Result(false, GetMessage("MAIN_TMP_FILE_ERROR"));
1804 }
1805
1806 $res = CIntranetSearchConverters::OnSearchGetFileContent($tmp);
1807 unlink($tmp);
1808
1809 if (is_array($res) && str_contains($res['CONTENT'], 'SUCCESS'))
1810 {
1811 return true;
1812 }
1813
1814 $strError = GetMessage("MAIN_SC_SEARCH_INCORRECT") . "<br>\n";
1815 if ($res === false && function_exists('exec'))
1816 {
1817 exec('catdoc -V', $output, $return_var);
1818 if ($return_var === 0)
1819 {
1820 $version = $output[0];
1821 if (str_contains($version, '0.94.4') || str_contains($version, '0.94.3'))
1822 {
1823 $strError .= GetMessage('MAIN_CATDOC_WARN', ['#VERSION#' => $version]);
1824 }
1825 }
1826 }
1827
1828 return $this->Result(false, $strError);
1829 }
1830
1832 {
1833 $tmp = $_SERVER['DOCUMENT_ROOT'] . '/bitrix/tmp/success.txt';
1834 if (!CheckDirPath($tmp) || !file_put_contents($tmp, 'SUCCESS'))
1835 {
1836 return $this->Result(false, GetMessage("MAIN_TMP_FILE_ERROR"));
1837 }
1838
1839 $strRequest = "GET " . "/bitrix/admin/site_checker.php?test_type=fast_download&unique_id=" . checker_get_unique_id() . " HTTP/1.1\r\n";
1840 $strRequest .= "Host: " . $this->host . "\r\n";
1841 $strRequest .= "\r\n";
1842
1843 if (!$res = $this->ConnectToHost())
1844 {
1845 return false;
1846 }
1847 if (IsHttpResponseSuccess($res, $strRequest))
1848 {
1849 $retVal = COption::GetOptionString('main', 'bx_fast_download', 'N') == 'Y' ? true : $this->Result(false, GetMessage("MAIN_FAST_DOWNLOAD_SUPPORT"));
1850 }
1851 else
1852 {
1853 $retVal = COption::GetOptionString('main', 'bx_fast_download', 'N') == 'N' ? $this->Result(false, GetMessage("MAIN_SC_NOT_SUPPORTED")) : $this->Result(false, GetMessage("MAIN_FAST_DOWNLOAD_ERROR"));
1854 }
1855 unlink($tmp);
1856 return $retVal;
1857 }
1858
1860 {
1861 $region = Application::getInstance()->getLicense()->getRegion();
1862
1863 if (in_array($region, ['ru', 'by', 'kz']))
1864 {
1865 $checker = 'checker.bitrix24.tech';
1866 }
1867 else
1868 {
1869 $checker = 'checker.internal.bitrix24.com';
1870 }
1871
1872 $retVal = null;
1873 $strRes = '';
1874
1875 if (preg_match('#^(127|10|172\.16|192\.168)\.#', $this->host))
1876 {
1877 $status = 0;
1878 }
1879 else
1880 {
1881 $strRequest =
1882 'GET /check/?license_hash=' . LICENSE_HASH . '&host=' . urlencode($this->host) . '&port=' . urlencode($this->port) . '&https=' . ($this->ssl ? 'Y' : 'N') . ' HTTP/1.1' . "\r\n" .
1883 'host: ' . $checker . "\r\n" .
1884 "\r\n";
1885
1886 if (!$res = $this->ConnectToHost($checker, 80))
1887 {
1888 $this->arTestVars['check_access_fail'] = true;
1889 return $this->Result($retVal, GetMessage("MAIN_SC_NO_CONNECTTO", ['#HOST#' => $checker]));
1890 }
1891
1892 $strRes = GetHttpResponse($res, $strRequest, $strHeaders);
1893 PrintHTTP($strRequest, $strHeaders, $strRes);
1894 if (!preg_match('#^Status: (.+)$#m', $strRes, $regs))
1895 {
1896 $this->arTestVars['check_access_fail'] = true;
1897 return $this->Result($retVal, GetMessage("MAIN_SC_UNKNOWN_ANSWER", ['#HOST#' => $checker]));
1898 }
1899 $status = intval($regs[1]);
1900 }
1901
1902 if (!$status)
1903 {
1904 $this->arTestVars['check_access_fail'] = true;
1905 return $this->Result($retVal, GetMessage("MAIN_SC_NO_EXTERNAL_CONNECT_WARN"));
1906 }
1907
1908 if ($status != 200 && $status != 401)
1909 {
1910 $this->arTestVars['check_access_fail'] = true;
1911 echo $strRes;
1912 return $this->Result($retVal, GetMessage("MAIN_SC_EXTERNAL_ANSWER_INCORRECT"));
1913 }
1914
1915 if (!CModule::IncludeModule('pull'))
1916 {
1917 return $this->Result(null, GetMessage("MAIN_NO_PULL_MODULE"));
1918 }
1919 if (!CPullOptions::GetPushStatus())
1920 {
1921 return $this->Result(null, GetMessage("MAIN_NO_OPTION_PULL"));
1922 }
1923 if (!$ar = parse_url(str_replace('#DOMAIN#', $this->host, COption::GetOptionString('pull', 'path_to_mobile_listener' . ($this->ssl ? '_secure' : '')))))
1924 {
1925 return $this->Result(false, GetMessage("MAIN_SC_PATH_SUB"));
1926 }
1927 $sub_port = $ar['port'];
1928 if (!$sub_port)
1929 {
1930 $sub_port = 80;
1931 }
1932 if ($sub_port != $this->port)
1933 {
1934 $strRequest =
1935 'GET /check/?license_hash=' . LICENSE_HASH . '&host=' . urlencode($this->host) . '&port=' . urlencode($sub_port) . '&https=' . ($ar['scheme'] == 'https' ? 'Y' : 'N') . ' HTTP/1.1' . "\r\n" .
1936 'host: ' . $checker . "\r\n" .
1937 "\r\n";
1938
1939 if (!$res = $this->ConnectToHost($checker, 80))
1940 {
1941 return $this->Result($retVal, GetMessage("MAIN_SC_NO_CONNECTTO", ['#HOST#' => $checker]));
1942 }
1943 $strRes = GetHttpResponse($res, $strRequest, $strHeaders);
1944 PrintHTTP($strRequest, $strHeaders, $strRes);
1945 if (!preg_match('#^Status: (.+)$#m', $strRes, $regs))
1946 {
1947 return $this->Result($retVal, GetMessage("MAIN_SC_UNKNOWN_ANSWER", ['#HOST#' => $checker]));
1948 }
1949 $status = intval($regs[1]);
1950 if (!$status)
1951 {
1952 return $this->Result($retVal, GetMessage("MAIN_SC_NO_PULL_EXTERNAL_2"));
1953 }
1954 }
1955
1956 return true;
1957 }
1958
1959 function check_perf()
1960 {
1961 $arTime = [];
1962 $count = 3;
1963 for ($i = 0; $i < $count; $i++)
1964 {
1965 if (!$res = $this->ConnectToHost())
1966 {
1967 return false;
1968 }
1969
1970 $file = '';
1971 if (IsModuleInstalled('security'))
1972 {
1973 $file = COption::GetOptionString("security", "ipcheck_disable_file", "");
1974 COption::SetOptionString("security", "ipcheck_disable_file", $this->LogFile);
1975 }
1976 $strRequest = "GET " . "/bitrix/admin/site_checker.php?test_type=perf&unique_id=" . checker_get_unique_id() . "&i=" . $i . " HTTP/1.1\r\n";
1977 $strRequest .= "Host: " . $this->host . "\r\n";
1978 $strRequest .= "\r\n";
1979
1980 $strRes = GetHttpResponse($res, $strRequest, $strHeaders);
1981
1982 if (IsModuleInstalled('security'))
1983 {
1984 COption::SetOptionString("security", "ipcheck_disable_file", $file);
1985 }
1986
1987 if (!is_numeric($strRes))
1988 {
1989 PrintHTTP($strRequest, $strHeaders, $strRes);
1990 return $this->Result(false, GetMessage('SC_TEST_FAIL'));
1991 }
1992
1993 $arTime[] = doubleval($strRes);
1994 }
1995
1996 $r = doubleval($count) / array_sum($arTime);
1997 if ($r < 10)
1998 {
1999 $strResult = GetMessage("MAIN_PERF_VERY_LOW");
2000 }
2001 elseif ($r < 15)
2002 {
2003 $strResult = GetMessage("MAIN_PERF_LOW");
2004 }
2005 elseif ($r < 30)
2006 {
2007 $strResult = GetMessage("MAIN_PERF_MID");
2008 }
2009 else
2010 {
2011 $strResult = GetMessage("MAIN_PERF_HIGH");
2012 }
2013 return $this->Result($r >= 10, $strResult . ' (' . number_format($r, 2, ".", " ") . ' ' . GetMessage("MAIN_PAGES_PER_SECOND") . ')');
2014 }
2015
2016 function check_cache()
2017 {
2018 $dir = $_SERVER["DOCUMENT_ROOT"] . BX_PERSONAL_ROOT . "/cache";
2019 $file0 = $dir . "/" . md5(mt_rand());
2020 $file1 = $file0 . ".tmp";
2021 $file2 = $file0 . ".php";
2022 if (!file_exists($dir))
2023 {
2024 mkdir($dir, BX_DIR_PERMISSIONS);
2025 }
2026
2027 return ($f = fopen($file1, 'wb')) && (fclose($f)) && (rename($file1, $file2)) && (unlink($file2));
2028 }
2029
2030 function check_exec()
2031 {
2032 $path = '/bitrix' . '/site_check_exec.php';
2033 if (!($f = fopen($_SERVER['DOCUMENT_ROOT'] . $path, 'wb')))
2034 {
2035 return $this->Result(false, GetMessage('SC_CHECK_FILES'));
2036 }
2037
2038 chmod($_SERVER['DOCUMENT_ROOT'] . $path, BX_FILE_PERMISSIONS);
2039
2040 fwrite($f, '<' . '? echo "SUCCESS"; ?' . '>');
2041 fclose($f);
2042
2043 $strRequest = "GET " . $path . " HTTP/1.1\r\n";
2044 $strRequest .= "Host: " . $this->host . "\r\n";
2045 $strRequest .= "\r\n";
2046
2047 if ($res = $this->ConnectToHost())
2048 {
2049 $retVal = IsHttpResponseSuccess($res, $strRequest);
2050 }
2051 else
2052 {
2053 $retVal = false;
2054 }
2055
2056 unlink($_SERVER['DOCUMENT_ROOT'] . $path);
2057
2058 return $retVal;
2059 }
2060
2062 {
2063 if (function_exists('apache_get_modules'))
2064 {
2065 $arLoaded = apache_get_modules();
2066
2067 if (!in_array('mod_rewrite', $arLoaded))
2068 {
2069 return $this->Result(false, GetMessage('SC_WARN_MOD_REWRITE') . "<br>");
2070 }
2071
2072 $strError = '';
2073 if (in_array('mod_security', $arLoaded))
2074 {
2075 $strError .= GetMessage('SC_WARN_SECURITY') . "<br>";
2076 }
2077 if (in_array('mod_dav', $arLoaded) || in_array('mod_dav_fs', $arLoaded))
2078 {
2079 $strError .= GetMessage('SC_WARN_DAV') . "<br>";
2080 }
2081 if ($strError)
2082 {
2083 return $this->Result(null, $strError);
2084 }
2085 }
2086
2087 return $this->Result(true, GetMessage("MAIN_SC_NO_CONFLICT"));
2088 }
2089
2091 {
2092 $strError = '';
2093 foreach ([
2094 'restore.php',
2095 'bitrix_server_test.php',
2096 'bitrixsetup.php',
2097 'bitrix_install.php',
2098 'bitrix_setup.php',
2099 'bitrix6setup.php',
2100 'bitrix7setup.php',
2101 'bitrix8setup.php',
2102 'export_file.csv',
2103 '1c_bx_import.php',
2104 ] as $file)
2105 {
2106 if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/' . $file))
2107 {
2108 $strError .= GetMessage('SC_FILE_EXISTS') . ' ' . $file . "\n<br>";
2109 }
2110 if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/bitrix/' . $file))
2111 {
2112 $strError .= GetMessage('SC_FILE_EXISTS') . ' /bitrix/' . $file . "\n<br>";
2113 }
2114 if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/upload/' . $file))
2115 {
2116 $strError .= GetMessage('SC_FILE_EXISTS') . ' /upload/' . $file . "\n<br>";
2117 }
2118 }
2119 if ($strError)
2120 {
2121 return $this->Result(false, $strError);
2122 }
2123 return $this->Result(true, GetMessage("MAIN_SC_ABSENT_ALL"));
2124 }
2125
2127 {
2128 $file = $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/fileman/install/components/bitrix/player/mediaplayer/player';
2129 if (!file_exists($file))
2130 {
2131 return $this->Result(null, "File not found: " . $file);
2132 }
2133
2134 if (false === getimagesize($file))
2135 {
2136 return $this->Result(null, GetMessage('SC_SWF_WARN'));
2137 }
2138 return true;
2139 }
2140
2142 {
2143 $strSERVER = '';
2144 foreach (['SERVER_PORT', 'HTTPS', 'FCGI_ROLE', 'HTTP_HOST', 'SERVER_PROTOCOL'] as $var)
2145 {
2146 $strSERVER .= '&' . $var . '=' . urlencode($_SERVER[$var] ?? '');
2147 }
2148
2149 if (!$this->arTestVars['last_value'])
2150 {
2151 $strRequest = "GET " . "/bitrix/admin/site_checker.php?test_type=redirect_test&unique_id=" . checker_get_unique_id() . $strSERVER . " HTTP/1.1\r\n";
2152 $strRequest .= "Host: " . $this->host . "\r\n";
2153 $strRequest .= "\r\n";
2154
2155 if (!$res = $this->ConnectToHost())
2156 {
2157 return false;
2158 }
2159
2160 $strRes = GetHttpResponse($res, $strRequest, $strHeaders);
2161
2162 if (preg_match('#Location: (.+)#i', $strHeaders, $regs))
2163 {
2164 $url = trim($regs[1]);
2165 if (!$url)
2166 {
2167 PrintHTTP($strRequest, $strHeaders, $strRes);
2168 return false;
2169 }
2170
2171 $this->arTestVars['last_value'] = $url;
2172 $this->test_percent = 50;
2173
2174 return true;
2175 }
2176
2177 PrintHTTP($strRequest, $strHeaders, $strRes);
2178 return false;
2179 }
2180 else
2181 {
2182 $url = $this->arTestVars['last_value'];
2183 if (!$url)
2184 {
2185 return false;
2186 }
2187
2188 $ar = parse_url($url);
2189
2190 $host = $ar['host'];
2191 $ssl = $ar['scheme'] == 'https' ? 'ssl://' : '';
2192 $port = intval($ar['port']) ?: ($ssl ? 443 : 80);
2193
2194 $strRequest = "GET " . "/bitrix/admin/site_checker.php?test_type=redirect_test&unique_id=" . checker_get_unique_id() . $strSERVER . "&done=Y HTTP/1.1\r\n";
2195 $strRequest .= "Host: " . $host . "\r\n";
2196 $strRequest .= "\r\n";
2197
2198 if ($res = $this->ConnectToHost($host, $port, $ssl))
2199 {
2200 return IsHttpResponseSuccess($res, $strRequest);
2201 }
2202 return false;
2203 }
2204 }
2205
2206 function check_sites()
2207 {
2208 $strError = '';
2209 $bUtf = false;
2210 $bChar = false;
2211 $arDocRoot = [];
2212
2213 $rs = CSite::GetList('', '', ['ACTIVE' => 'Y']);
2214 while ($f = $rs->Fetch())
2215 {
2216 $arDocRoot[] = trim($f['DOC_ROOT']);
2217 $bFound = str_contains(strtolower($f['CHARSET']), 'utf');
2218
2219 $bUtf = $bUtf || $bFound;
2220 $bChar = $bChar || !$bFound;
2221 }
2222
2223 if (count($arDocRoot) == 1)
2224 {
2225 if ($root = $arDocRoot[0])
2226 {
2227 $strError = GetMessage('SC_PATH_FAIL_SET') . ' <i>' . htmlspecialcharsbx($root) . '</i><br>';
2228 }
2229 }
2230 else
2231 {
2232 foreach ($arDocRoot as $root)
2233 {
2234 if ($root)
2235 {
2236 if (!is_readable($root . '/bitrix'))
2237 {
2238 $strError .= GetMessage('SC_NO_ROOT_ACCESS') . ' <i>' . htmlspecialcharsbx($root) . '/bitrix</i><br>';
2239 }
2240 }
2241 }
2242 }
2243
2244 if ($bUtf && $bChar)
2245 {
2246 $strError .= GetMessage("SC_SITE_CHARSET_FAIL");
2247 }
2248
2249 if ($strError)
2250 {
2251 return $this->Result(false, $strError);
2252 }
2253
2254 return $this->Result(true, GetMessage("MAIN_SC_CORRECT"));
2255 }
2256
2258 {
2259 $strRequest = "GET " . "/bitrix/admin/site_checker.php?test_type=pcre_recursion_test&unique_id=" . checker_get_unique_id() . " HTTP/1.1\r\n";
2260 $strRequest .= "Host: " . $this->host . "\r\n";
2261 $strRequest .= "\r\n";
2262
2263 if ($res = $this->ConnectToHost())
2264 {
2265 if ('SUCCESS' == $strRes = GetHttpResponse($res, $strRequest, $strHeaders))
2266 {
2267 return true;
2268 }
2269 if ($strRes == 'CLEAN')
2270 {
2271 return $this->Result(null, GetMessage('SC_PCRE_CLEAN'));
2272 }
2273 }
2274 return false;
2275 }
2276
2278 {
2279 $strRequest = "GET " . "/bitrix/admin/site_checker.php?test_type=method_exists&unique_id=" . checker_get_unique_id() . " HTTP/1.1\r\n";
2280 $strRequest .= "Host: " . $this->host . "\r\n";
2281 $strRequest .= "\r\n";
2282
2283 if ($res = $this->ConnectToHost())
2284 {
2285 return IsHttpResponseSuccess($res, $strRequest);
2286 }
2287 return false;
2288 }
2289
2291 {
2292 $connection = Application::getConnection();
2293 $helper = $connection->getSqlHelper();
2294
2295 $this->arTestVars['check_bx_crontab'] = false;
2296 if (defined('BX_CRONTAB'))
2297 {
2298 return $this->Result(false, GetMessage("MAIN_BX_CRONTAB_DEFINED"));
2299 }
2300
2301 $bCron = COption::GetOptionString("main", "agents_use_crontab", "N") == 'Y' || defined('BX_CRONTAB_SUPPORT') && BX_CRONTAB_SUPPORT === true || COption::GetOptionString("main", "check_agents", "Y") != 'Y';
2302 if ($bCron)
2303 {
2304 if (!$connection->query('SELECT LAST_EXEC FROM b_agent WHERE LAST_EXEC > ' . $helper->addDaysToDateTime(-1) . ' AND IS_PERIOD = \'N\' LIMIT 1')->fetch())
2305 {
2306 return $this->Result(false, GetMessage("MAIN_CRON_NO_START"));
2307 }
2308 $this->arTestVars['check_bx_crontab'] = true;
2309 return true;
2310 }
2311 return $this->Result(null, GetMessage("MAIN_AGENTS_HITS"));
2312 }
2313
2315 {
2316 $connection = Application::getConnection();
2317
2318 $PgSql_vercheck_min = '11.0.0';
2319
2320 $ver = $connection->getVersion()[0];
2321 if (version_compare($ver, $PgSql_vercheck_min, '<'))
2322 {
2323 return $this->Result(false, GetMessage('SC_PGSQL_ERR_VER', [
2324 '#CUR#' => $ver,
2325 '#REQ#' => $PgSql_vercheck_min,
2326 ]));
2327 }
2328
2329 return true;
2330 }
2331
2333 {
2334 $connection = Application::getConnection();
2335 $helper = $connection->getSqlHelper();
2336 $strError = '';
2337
2338 $f = $connection->query('select datctype as LC_CTYPE from pg_database where datname = \'' . $helper->forSql($connection->getDatabase()) . '\'')->fetch();
2339 $collation_database = $f['LC_CTYPE'];
2340
2341 if (!preg_match('/\.(UTF-8|UTF8)$/i', $collation_database))
2342 {
2343 $strError = GetMessage('SC_DATABASE_LC_CTYPE', ['#VAL0#' => $collation_database]);
2344 }
2345
2346 if (!$strError)
2347 {
2348 return true;
2349 }
2350
2351 $this->arTestVars['db_charset_fail'] = true;
2352 return $this->Result(false, $strError);
2353 }
2354
2356 {
2357 $connection = Application::getConnection();
2358 $strError = '';
2359
2360 if ($this->arTestVars['check_mbstring_fail'])
2361 {
2362 return $this->Result(null, GetMessage('SC_MBSTRING_NA'));
2363 }
2364
2365 $f = $connection->query('SHOW client_encoding')->fetch();
2366 $character_set_connection = $f['CLIENT_ENCODING'];
2367
2368 if ($character_set_connection != 'UTF8')
2369 {
2370 $strError = GetMessage('SC_CONNECTION_CHARSET_WRONG', ['#VAL#' => 'utf8', '#VAL1#' => $character_set_connection]);
2371 }
2372
2373 echo 'character_set_connection=' . $character_set_connection;
2374
2375 if (!$strError)
2376 {
2377 return true;
2378 }
2379
2380 $this->arTestVars['check_connection_charset_fail'] = true;
2381
2382 return $this->Result(false, $strError);
2383 }
2384
2385 ##############################
2386 # MYSQL Tests follow
2387 ##############################
2389 {
2390 global $DB;
2391
2392 $MySql_vercheck_min = "5.0.0";
2393
2394 $ver = $DB->GetVersion();
2395 if (version_compare($ver, $MySql_vercheck_min, '<'))
2396 {
2397 return $this->Result(false, GetMessage('SC_MYSQL_ERR_VER', ['#CUR#' => $ver, '#REQ#' => $MySql_vercheck_min]));
2398 }
2399
2400 if ($ver == '4.1.21' // sorting
2401 || $ver == '5.1.34' // auto_increment
2402 || $ver == '5.0.41' // search
2403// || $ver == '5.1.66' // forum page navigation
2404 )
2405 {
2406 return $this->Result(false, GetMessage('SC_DB_ERR') . ' ' . $ver);
2407 }
2408
2409 return true;
2410 }
2411
2413 {
2414 global $DB;
2415
2416 $errors = [];
2417
2418 $f = $DB->Query('SHOW VARIABLES LIKE \'innodb_strict_mode\'')->Fetch();
2419 if (strtoupper($f['Value']) != 'OFF')
2420 {
2421 $errors[] = GetMessage('SC_DB_ERR_INNODB_STRICT', ['#VALUE#' => $f['Value']]);
2422 }
2423
2424 $f = $DB->Query('SHOW VARIABLES LIKE \'sql_mode\'')->Fetch();
2425 if ($f['Value'] <> '')
2426 {
2427 $errors[] = GetMessage('SC_DB_ERR_MODE') . ' ' . $f['Value'];
2428 }
2429
2430 $f = $DB->Query('SHOW VARIABLES LIKE \'innodb_large_prefix\'')->Fetch();
2431 if ($f)
2432 {
2433 if ($f['Value'] === '0' || $f['Value'] === 'OFF')
2434 {
2435 $errors[] = GetMessage('SC_DB_ERR_INNODB_LARGE_PREFIX', ['#VALUE#' => $f['Value']]);
2436 }
2437 }
2438
2439 $f = $DB->Query('SHOW VARIABLES LIKE \'innodb_default_row_format\'')->Fetch();
2440 if ($f)
2441 {
2442 if (strtolower($f['Value']) !== 'dynamic')
2443 {
2444 $errors[] = GetMessage('SC_DB_ERR_INNODB_DEFAULT_ROW_FORMAT', ['#VALUE#' => $f['Value']]);
2445 }
2446 }
2447
2448 $f = $DB->Query('SHOW VARIABLES LIKE \'default_storage_engine\'')->Fetch();
2449 if ($f)
2450 {
2451 if (strtolower($f['Value']) !== 'innodb')
2452 {
2453 $errors[] = GetMessage('SC_DB_ERR_DEFAULT_STORAGE_ENGINE', ['#VALUE#' => $f['Value']]);
2454 }
2455 }
2456
2457 return $errors ? $this->Result(false, implode('<br>', $errors)) : true;
2458 }
2459
2461 {
2462 global $DB;
2463
2464 $s = time();
2465 while ($s == time())
2466 {
2467 ;
2468 }
2469 $s++;
2470 $res = $DB->Query('SELECT NOW() AS A');
2471 $f = $res->Fetch();
2472 if (($diff = abs($s - strtotime($f['A']))) <= 1)
2473 {
2474 return true;
2475 }
2476 return $this->Result(false, GetMessage('SC_TIME_DIFF', ['#VAL#' => $diff]));
2477 }
2478
2480 {
2481 global $DB;
2482 $time = time();
2483
2484 $strError = '';
2485 $i = 0;
2486 $res = $DB->Query('SHOW TABLES');
2487 $cnt = $res->SelectedRowsCount();
2488 while ($f = $res->Fetch())
2489 {
2490 $i++;
2491 $table = current($f);
2492
2493 if ($this->arTestVars['last_value'])
2494 {
2495 if ($this->arTestVars['last_value'] == $table)
2496 {
2497 unset($this->arTestVars['last_value']);
2498 }
2499 continue;
2500 }
2501
2502 if (!$this->fix_mode)
2503 {
2504 $res0 = $DB->Query('CHECK TABLE ' . $DB->quote($table));
2505 }
2506 else
2507 {
2508 $res0 = $DB->Query('REPAIR TABLE ' . $DB->quote($table));
2509 }
2510
2511 $f0 = $res0->Fetch();
2512 if ($f0['Msg_type'] == 'error' || $f0['Msg_type'] == 'warning')
2513 {
2514 $strError .= GetMessage('SC_TABLE_ERR', ['#VAL#' => $table]) . ' ' . $f0['Msg_text'] . "\n<br>";
2515 }
2516
2517 if (time() - $time >= $this->timeout)
2518 {
2519 $this->arTestVars['last_value'] = $table;
2520 $this->test_percent = floor($i / $cnt * 100);
2521 return true;
2522 }
2523 }
2524
2525 if (!$strError)
2526 {
2527 return true;
2528 }
2529
2530 if (!$this->fix_mode)
2531 {
2532 $this->arTestVars['check_table_status_fail'] = true;
2533 echo $strError; // to log
2534 return $this->Result(false, GetMessage('SC_TABLES_NEED_REPAIR') . fix_link(1));
2535 }
2536
2537 return $this->Result(false, $strError);
2538 }
2539
2541 {
2542 global $DB;
2543 $strError = '';
2544
2545 if (!empty($this->arTestVars['check_mbstring_fail']))
2546 {
2547 return $this->Result(null, GetMessage('SC_MBSTRING_NA'));
2548 }
2549
2550 $res = $DB->Query('SHOW VARIABLES LIKE "character_set_connection"');
2551 $f = $res->Fetch();
2552 $character_set_connection = $f['Value'];
2553
2554 $res = $DB->Query('SHOW VARIABLES LIKE "character_set_results"');
2555 $f = $res->Fetch();
2556 $character_set_results = $f['Value'];
2557
2558 $res = $DB->Query('SHOW VARIABLES LIKE "collation_connection"');
2559 $f = $res->Fetch();
2560 $collation_connection = $f['Value'];
2561
2562 if (!in_array($character_set_connection, ['utf8', 'utf8mb3', 'utf8mb4']))
2563 {
2564 $strError = GetMessage("SC_CONNECTION_CHARSET_WRONG", ['#VAL#' => 'utf8', '#VAL1#' => $character_set_connection]);
2565 }
2566 elseif (!preg_match('/^(utf8|utf8mb3|utf8mb4)_/', $collation_connection))
2567 {
2568 $strError = GetMessage("SC_CONNECTION_COLLATION_WRONG_UTF", ['#VAL#' => $collation_connection]);
2569 }
2570
2571 if (!$strError && $character_set_connection != $character_set_results)
2572 {
2573 $strError = GetMessage('SC_CHARSET_CONN_VS_RES', ['#CONN#' => $character_set_connection, '#RES#' => $character_set_results]);
2574 }
2575
2576 echo 'character_set_connection=' . $character_set_connection . ', collation_connection=' . $collation_connection . ', character_set_results=' . $character_set_results;
2577
2578 if (!$strError)
2579 {
2580 return true;
2581 }
2582
2583 $this->arTestVars['check_connection_charset_fail'] = true;
2584
2585 return $this->Result(false, $strError);
2586 }
2587
2589 {
2590 global $DB;
2591 if (!empty($this->arTestVars['check_mbstring_fail']))
2592 {
2593 return $this->Result(null, GetMessage('SC_MBSTRING_NA'));
2594 }
2595 elseif (!empty($this->arTestVars['check_table_status_fail']))
2596 {
2597 return $this->Result(null, GetMessage('SC_TABLES_NEED_REPAIR'));
2598 }
2599 elseif (!empty($this->arTestVars['check_connection_charset_fail']))
2600 {
2601 return $this->Result(null, GetMessage('SC_CONNECTION_CHARSET_NA'));
2602 }
2603
2604 $strError = '';
2605
2606 $res = $DB->Query('SHOW VARIABLES LIKE \'character_set_connection\'');
2607 $f = $res->Fetch();
2608 $character_set_connection = $f['Value'];
2609
2610 $res = $DB->Query('SHOW VARIABLES LIKE \'collation_connection\'');
2611 $f = $res->Fetch();
2612 $collation_connection = $f['Value'];
2613
2614 $res = $DB->Query('SHOW VARIABLES LIKE \'character_set_database\'');
2615 $f = $res->Fetch();
2616 $character_set_database = $f['Value'];
2617
2618 $res = $DB->Query('SHOW VARIABLES LIKE \'collation_database\'');
2619 $f = $res->Fetch();
2620 $collation_database = $f['Value'];
2621
2622 if ($this->fix_mode)
2623 {
2624 if (!$DB->Query($sql = 'ALTER DATABASE ' . $DB->quote($DB->DBName) . ' DEFAULT CHARACTER SET ' . $character_set_connection . ' COLLATE ' . $collation_connection, true))
2625 {
2626 $strError = $sql . ' [' . $DB->db_Error . ']';
2627 }
2628 }
2629 else
2630 {
2631 if ($character_set_connection != $character_set_database)
2632 {
2633 $strError = GetMessage('SC_DATABASE_CHARSET_DIFF', ['#VAL0#' => $character_set_connection, '#VAL1#' => $character_set_database]) . fix_link();
2634 }
2635 elseif ($collation_database != $collation_connection)
2636 {
2637 $strError = GetMessage('SC_DATABASE_COLLATION_DIFF', ['#VAL0#' => $collation_connection, '#VAL1#' => $collation_database]) . fix_link();
2638 }
2639 }
2640
2641 echo 'CHARSET=' . $character_set_database . ', COLLATION=' . $collation_database;
2642
2643 if (!$strError)
2644 {
2645 return true;
2646 }
2647
2648 $this->arTestVars['db_charset_fail'] = true;
2649 return $this->Result(false, $strError);
2650 }
2651
2653 {
2654 global $DB;
2655 $strError = '';
2656
2657 $res = $DB->Query("
2658 select
2659 TABLE_NAME
2660 ,ENGINE
2661 from
2662 information_schema.TABLES
2663 where
2664 TABLE_SCHEMA = '" . $DB->ForSql($DB->DBName) . "'
2665 and TABLE_TYPE = 'BASE TABLE'
2666 and TABLE_NAME like 'b\_%'
2667 and CREATE_OPTIONS <> _ascii'row_format=DYNAMIC'
2668 and (
2669 UPPER(ROW_FORMAT) in ('REDUNDANT', 'COMPACT')
2670 or ENGINE <> 'InnoDB'
2671 )
2672 ");
2673 while ($f = $res->Fetch())
2674 {
2675 if ($this->fix_mode)
2676 {
2677 $alter = 'ALTER TABLE ' . $DB->quote($f['TABLE_NAME']) . ' ROW_FORMAT=Dynamic ENGINE=InnoDB';
2678 $res0 = $DB->Query($alter, true);
2679 if (!$res0)
2680 {
2681 $strError .= $alter . ' [' . $DB->db_Error . ']';
2682 break;
2683 }
2684 }
2685 else
2686 {
2687 $strError .= GetMessage('SC_TABLE_ROW_FORMAT', ['#TABLE#' => $f['TABLE_NAME']]) . '<br>';
2688 $this->arTestVars['iError']++;
2689 $this->arTestVars['iErrorAutoFix']++;
2690 }
2691 }
2692
2693 if (!$strError)
2694 {
2695 return true;
2696 }
2697
2698 $this->arTestVars['table_format_fail'] = true;
2699
2700 if ($this->fix_mode)
2701 {
2702 return $this->Result(false, $strError);
2703 }
2704 else
2705 {
2706 echo $strError; // to log
2707 return $this->Result(false, GetMessage('SC_TABLE_ROW_FORMAT_ERRORS', [
2708 '#VAL#' => intval($this->arTestVars['iError']),
2709 '#VAL1#' => intval($this->arTestVars['iErrorAutoFix']),
2710 ]) . ($this->arTestVars['iErrorAutoFix'] > 0 ? fix_link() : ''));
2711 }
2712 }
2713
2715 {
2716 global $DB;
2717 $strError = '';
2718
2719 if (!empty($this->arTestVars['check_mbstring_fail']))
2720 {
2721 return $this->Result(null, GetMessage('SC_MBSTRING_NA'));
2722 }
2723 elseif (!empty($this->arTestVars['check_table_status_fail']))
2724 {
2725 return $this->Result(null, GetMessage('SC_TABLES_NEED_REPAIR'));
2726 }
2727 elseif (!empty($this->arTestVars['check_connection_charset_fail']))
2728 {
2729 return $this->Result(null, GetMessage('SC_CONNECTION_CHARSET_NA'));
2730 }
2731 elseif (!empty($this->arTestVars['db_charset_fail']))
2732 {
2733 return $this->Result(null, GetMessage('SC_TABLE_CHECK_NA'));
2734 }
2735 elseif (!empty($this->arTestVars['table_format_fail']))
2736 {
2737 return $this->Result(null, GetMessage('SC_TABLE_ROW_FORMAT_NA'));
2738 }
2739
2740 $res = $DB->Query('SHOW VARIABLES LIKE "character_set_database"');
2741 $f = $res->Fetch();
2742 $charset = trim($f['Value']);
2743
2744 $res = $DB->Query('SHOW VARIABLES LIKE "collation_database"');
2745 $f = $res->Fetch();
2746 $collation = trim($f['Value']);
2747
2748 $time = time();
2749 $i = 0;
2750 $res = $DB->Query('SHOW TABLES LIKE \'b\_%\'');
2751 $cnt = $res->SelectedRowsCount();
2752
2753 $arExclusion = [
2754 'b_sale_loc_search_word' => 'WORD',
2755 'b_search_content_stem' => 'STEM',
2756 'b_search_content_freq' => 'STEM',
2757 'b_search_stem' => 'STEM',
2758 'b_search_tags' => 'NAME',
2759 'b_translate_path' => 'NAME',
2760 'b_translate_phrase' => 'CODE',
2761 ];
2762 while ($f = $res->Fetch())
2763 {
2764 $i++;
2765 $table = current($f);
2766
2767 if (!empty($this->arTestVars['last_value']))
2768 {
2769 if ($this->arTestVars['last_value'] == $table)
2770 {
2771 unset($this->arTestVars['last_value']);
2772 }
2773 continue;
2774 }
2775
2776 $res0 = $DB->Query('SHOW CREATE TABLE ' . $DB->quote($table), true);
2777 if ($res0 === false)
2778 {
2779 if ($this->fix_mode)
2780 {
2781 $DB->Query('DROP TABLE ' . $DB->quote($table), true);
2782 }
2783 else
2784 {
2785 $strError .= GetMessage('SC_TABLE_BROKEN', ['#TABLE#' => $table]) . "<br>";
2786 $this->arTestVars['iError']++;
2787 $this->arTestVars['iErrorAutoFix']++;
2788 }
2789 continue;
2790 }
2791 $f0 = $res0->Fetch();
2792
2793 if (preg_match('/DEFAULT CHARSET=([a-z0-9\-_]+)/i', $f0['Create Table'], $regs))
2794 {
2795 $t_charset = $regs[1];
2796 if (preg_match('/COLLATE=([a-z0-9\-_]+)/i', $f0['Create Table'], $regs))
2797 {
2798 $t_collation = $regs[1];
2799 }
2800 else
2801 {
2802 $res0 = $DB->Query('SHOW CHARSET LIKE \'' . $DB->ForSql(str_replace('_', '\_', $t_charset)) . '\'');
2803 $f0 = $res0->Fetch();
2804 $t_collation = $f0['Default collation'];
2805 }
2806 }
2807 else
2808 {
2809 $res0 = $DB->Query('SHOW TABLE STATUS LIKE \'' . $DB->ForSql(str_replace('_', '\_', $table)) . '\'');
2810 $f0 = $res0->Fetch();
2811 if (!$t_collation = $f0['Collation'])
2812 {
2813 continue;
2814 }
2815 $t_charset = getCharsetByCollation($t_collation);
2816 }
2817
2818 if ($charset != $t_charset)
2819 {
2820 // table charset differs
2821 if (!$this->fix_mode)
2822 {
2823 $strError .= GetMessage('SC_DB_MISC_CHARSET', ['#TABLE#' => $table, '#VAL1#' => $t_charset, '#VAL0#' => $charset]) . "<br>";
2824 $this->arTestVars['iError']++;
2825 if ($this->force_repair)
2826 {
2827 $this->arTestVars['iErrorAutoFix']++;
2828 }
2829 }
2830 elseif ($this->force_repair && !$DB->Query($sql = 'ALTER TABLE ' . $DB->quote($table) . ' CHARACTER SET ' . $charset, true))
2831 {
2832 $strError .= $sql . ' [' . $DB->db_Error . ']';
2833 break;
2834 }
2835 }
2836 elseif ($t_collation != $collation)
2837 { // table collation differs
2838 if (!$this->fix_mode)
2839 {
2840 $strError .= GetMessage('SC_COLLATE_WARN', ['#TABLE#' => $table, '#VAL1#' => $t_collation, '#VAL0#' => $collation]) . "<br>";
2841 $this->arTestVars['iError']++;
2842 $this->arTestVars['iErrorAutoFix']++;
2843 }
2844 elseif (!$DB->Query($sql = 'ALTER TABLE ' . $DB->quote($table) . ' COLLATE ' . $collation, true))
2845 {
2846 $strError .= $sql . ' [' . $DB->db_Error . ']';
2847 break;
2848 }
2849 }
2850
2851 // fields check
2852 $arFix = [];
2853 $res0 = $DB->Query("SHOW FULL COLUMNS FROM " . $DB->quote($table));
2854 while ($f0 = $res0->Fetch())
2855 {
2856 $f_collation = $f0['Collation'];
2857 if ($f_collation === null || $f_collation === "NULL")
2858 {
2859 continue;
2860 }
2861
2862 $f_charset = getCharsetByCollation($f_collation);
2863
2864 if ($charset != $f_charset)
2865 {
2866 // field charset differs
2867 if (!$this->fix_mode)
2868 {
2869 $strError .= GetMessage('SC_TABLE_CHARSET_WARN', ['#TABLE#' => $table, '#VAL0#' => $charset, '#VAL1#' => $f_charset, '#FIELD#' => $f0['Field']]) . "<br>";
2870 $this->arTestVars['iError']++;
2871 if ($this->force_repair)
2872 {
2873 $this->arTestVars['iErrorAutoFix']++;
2874 }
2875 }
2876 elseif ($this->force_repair)
2877 {
2878 $arFix[] = ' MODIFY ' . $DB->quote($f0['Field'])
2879 . ' ' . $f0['Type']
2880 . ' CHARACTER SET ' . $charset
2881 . ($f0['Null'] == 'YES' ? ' NULL' : ' NOT NULL')
2882 . ($f0['Default'] === null ? ($f0['Null'] == 'YES' ? ' DEFAULT NULL ' : '') : ' DEFAULT ' . ($f0['Type'] == 'timestamp' && $f0['Default'] ? $f0['Default'] : '"' . $DB->ForSQL($f0['Default']) . '"'))
2883 . ' ' . str_ireplace('DEFAULT_GENERATED', '', $f0['Extra'])
2884 . ($f0['Comment'] ? ' COMMENT \'' . $DB->ForSql($f0['Comment']) . '\'' : '');
2885 }
2886 }
2887 elseif ($collation != $f_collation)
2888 {
2889 if (!empty($arExclusion[$table]) && strtoupper($f0['Field']) == $arExclusion[$table])
2890 {
2891 continue;
2892 }
2893
2894 // field collation differs
2895 if (!$this->fix_mode)
2896 {
2897 $strError .= GetMessage('SC_FIELDS_COLLATE_WARN', ['#TABLE#' => $table, '#VAL0#' => $collation, '#VAL1#' => $f_collation, '#FIELD#' => $f0['Field']]) . "<br>";
2898
2899 if (!isset($this->arTestVars['iError']))
2900 {
2901 $this->arTestVars['iError'] = 0;
2902 }
2903 $this->arTestVars['iError']++;
2904
2905 if (!isset($this->arTestVars['iErrorAutoFix']))
2906 {
2907 $this->arTestVars['iErrorAutoFix'] = 0;
2908 }
2909 $this->arTestVars['iErrorAutoFix']++;
2910 }
2911 else
2912 {
2913 $arFix[] = ' MODIFY ' . $DB->quote($f0['Field'])
2914 . ' ' . $f0['Type']
2915 . ' COLLATE ' . $collation . ($f0['Null'] == 'YES' ? ' NULL' : ' NOT NULL')
2916 . ($f0['Default'] === null ? ($f0['Null'] == 'YES' ? ' DEFAULT NULL ' : '') : ' DEFAULT ' . ($f0['Type'] == 'timestamp' && $f0['Default'] ? $f0['Default'] : '"' . $DB->ForSQL($f0['Default']) . '"'))
2917 . ' ' . str_ireplace('DEFAULT_GENERATED', '', $f0['Extra'])
2918 . ($f0['Comment'] ? ' COMMENT \'' . $DB->ForSql($f0['Comment']) . '\'' : '');
2919 }
2920 }
2921 }
2922
2923 if ($this->fix_mode && count($arFix))
2924 {
2925 if (!$DB->Query($sql = 'ALTER TABLE ' . $DB->quote($table) . ' ' . implode(",\n", $arFix), true))
2926 {
2927 $strError .= $sql . ' [' . $DB->db_Error . ']';
2928 break;
2929 }
2930 }
2931
2932 if (time() - $time >= $this->timeout)
2933 {
2934 $this->arTestVars['last_value'] = $table;
2935 $this->test_percent = floor($i / $cnt * 100);
2936 return true;
2937 }
2938 }
2939
2940 if (!$strError)
2941 {
2942 return true;
2943 }
2944
2945 $this->arTestVars['table_charset_fail'] = true;
2946
2947 if ($this->fix_mode)
2948 {
2949 return $this->Result(false, $strError);
2950 }
2951 else
2952 {
2953 echo $strError; // to log
2954 return $this->Result(false, GetMessage('SC_CHECK_TABLES_ERRORS', ['#VAL#' => intval($this->arTestVars['iError']), '#VAL1#' => intval($this->arTestVars['iErrorAutoFix'])]) . ($this->arTestVars['iErrorAutoFix'] > 0 ? fix_link() : ''));
2955 }
2956 }
2957
2959 {
2960 global $DB;
2961 $strError = '';
2962
2963 $arInsertExclude = [
2964 'b_seo_search_engine' => 1,
2965 'b_hot_keys_code' => 1,
2966 ];
2967
2968 if (!empty($this->arTestVars['table_charset_fail']))
2969 {
2970 return $this->Result(null, GetMessage('SC_TABLE_COLLATION_NA'));
2971 }
2972 elseif (!empty($this->arTestVars['table_format_fail']))
2973 {
2974 return $this->Result(null, GetMessage('SC_TABLE_ROW_FORMAT_NA'));
2975 }
2976
2977 $DB->Query("SET SQL_MODE=''");
2978
2979 $module = '';
2980 $cnt = $iCurrent = 0;
2981 if ($dir = opendir($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules'))
2982 {
2983 while (false !== ($item = readdir($dir)))
2984 {
2985 if (str_contains($item, '.')) // skipping all external modules
2986 {
2987 continue;
2988 }
2989
2990 $cnt++;
2991
2992 if (!empty($this->arTestVars['last_value']))
2993 {
2994 $iCurrent++;
2995 if ($this->arTestVars['last_value'] == $item)
2996 {
2997 unset($this->arTestVars['last_value']);
2998 }
2999 }
3000 elseif (!$module)
3001 {
3002 $module = $item;
3003 }
3004 }
3005 closedir($dir);
3006 }
3007 else
3008 {
3009 return false;
3010 }
3011
3012 $file = $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $module . '/install/db/mysql/install.sql';
3013 if (!file_exists($file))
3014 {
3015 $file = $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $module . '/install/mysql/install.sql';
3016 }
3017 if (file_exists($file)) // uses database...
3018 {
3019 $arTableColumns = [];
3020 $bModuleInstalled = ModuleTable::getById($module)->fetch();
3021
3022 if (false === ($query = file_get_contents($file)))
3023 {
3024 return false;
3025 }
3026
3027 $arTables = [];
3028 $arQuery = $DB->ParseSQLBatch(str_replace("\r", "", $query));
3029 foreach ($arQuery as $sql)
3030 {
3031 if (preg_match('#^(CREATE TABLE )(IF NOT EXISTS)? *`?([a-z0-9_]+)`?(.*);?$#mis', $sql, $regs))
3032 {
3033 $table = $regs[3];
3034 if (str_starts_with($table, 'site_checker_'))
3035 {
3036 continue;
3037 }
3038
3039 $bTableExists = $DB->Query('SHOW TABLES LIKE \'' . $DB->ForSql(str_replace('_', '\_', $table)) . '\'')->Fetch();
3040 if (!$bTableExists && $bModuleInstalled)
3041 {
3042 if ($this->fix_mode)
3043 {
3044 if (!$DB->Query($sql, true))
3045 {
3046 return $this->Result(false, 'Mysql Query Error: ' . $sql . ' [' . $DB->db_Error . ']');
3047 }
3048 }
3049 else
3050 {
3051 $strError .= GetMessage('SC_ERR_NO_TABLE', ['#TABLE#' => $table]) . "<br>";
3052 Application::getInstance()->getSession()['FixQueryList'][] = $sql;
3053 $this->arTestVars['iError'] = ($this->arTestVars['iError'] ?? 0) + 1;
3054 $this->arTestVars['iErrorAutoFix'] = ($this->arTestVars['iErrorAutoFix'] ?? 0) + 1;
3055 $this->arTestVars['cntNoTables'] = ($this->arTestVars['cntNoTables'] ?? 0) + 1;
3056 continue;
3057 }
3058 }
3059
3060 if ($bTableExists || $bModuleInstalled)
3061 {
3062 $arTables[$table] = $sql;
3063 $tmp_table = 'site_checker_' . $table;
3064 $DB->Query('DROP TABLE IF EXISTS ' . $DB->quote($tmp_table));
3065 $DB->Query($regs[1] . ' ' . $DB->quote($tmp_table) . $regs[4]);
3066 }
3067 }
3068 elseif (preg_match('#^(ALTER TABLE)( )?`?([a-z0-9_]+)`?(.*);?$#mis', $sql, $regs))
3069 {
3070 $table = $regs[3];
3071 if (!$arTables[$table])
3072 {
3073 continue;
3074 }
3075 $tmp_table = 'site_checker_' . $table;
3076 $DB->Query($regs[1] . ' ' . $DB->quote($tmp_table) . $regs[4]);
3077 }
3078 elseif (preg_match('#^INSERT INTO *`?([a-z0-9_]+)`?[^(]*\‍(?([^)]*)\‍)?[^V]*VALUES[^(]*\‍((.+)\‍);?$#mis', $sql, $regs))
3079 {
3080 $table = $regs[1];
3081 if (!$arTables[$table] || !empty($arInsertExclude[$table]))
3082 {
3083 continue;
3084 }
3085 $tmp_table = 'site_checker_' . $table;
3086
3087 if ($regs[2])
3088 {
3089 $arColumns = explode(',', $regs[2]);
3090 }
3091 else
3092 {
3093 if (!$arTableColumns[$tmp_table])
3094 {
3095 $rs = $DB->Query('SHOW COLUMNS FROM ' . $DB->quote($tmp_table));
3096 while ($f = $rs->Fetch())
3097 {
3098 $arTableColumns[$tmp_table][] = $f['Field'];
3099 }
3100 }
3101 $arColumns = $arTableColumns[$tmp_table];
3102 }
3103
3104 $strValues = $regs[3];
3105 $ar = explode(",", $strValues);
3106 $arValues = [];
3107 $i = 0;
3108 $str = '';
3109 foreach ($ar as $v)
3110 {
3111 $str .= ($str ? ',' : '') . $v;
3112 if (preg_match('#^ *(-?[0-9]+|\'.*\'|".*"|null|now\‍(\‍)) *$#i', $str))
3113 {
3114 $arValues[$i] = $str;
3115 $str = '';
3116 $i++;
3117 }
3118 }
3119
3120 if (!$str)
3121 {
3122 $sqlSelect = 'SELECT * FROM ' . $DB->quote($table) . ' WHERE 1=1 ';
3123 foreach ($arColumns as $k => $c)
3124 {
3125 $v = $arValues[$k];
3126 if (!preg_match('#null|now\‍(\‍)#i', $v))
3127 {
3128 $sqlSelect .= ' AND ' . $c . '=' . $v;
3129 }
3130 }
3131 $rs = $DB->Query($sqlSelect);
3132 if (!$rs->Fetch())
3133 {
3134 if ($this->fix_mode)
3135 {
3136 if (!$DB->Query($sql, true))
3137 {
3138 return $this->Result(false, 'Mysql Query Error: ' . $sql . ' [' . $DB->db_Error . ']');
3139 }
3140 }
3141 else
3142 {
3143 $strError .= GetMessage('SC_ERR_NO_VALUE', ['#TABLE#' => $table, '#SQL#' => $sql]) . "<br>";
3144 Application::getInstance()->getSession()['FixQueryList'][] = $sql;
3145 $this->arTestVars['iError'] = ($this->arTestVars['iError'] ?? 0) + 1;
3146 $this->arTestVars['iErrorAutoFix'] = ($this->arTestVars['iErrorAutoFix'] ?? 0) + 1;
3147 $this->arTestVars['cntNoValues'] = ($this->arTestVars['cntNoValues'] ?? 0) + 1;
3148 }
3149 }
3150 }
3151 else
3152 {
3153 echo "Error parsing SQL:\n" . $sql . "\n";
3154 }
3155 }
3156 }
3157
3158 if (file_exists($file = str_replace('/install.sql', '/install_ft.sql', $file)))
3159 {
3160 if (false === ($query = file_get_contents($file)))
3161 {
3162 return false;
3163 }
3164 $query = preg_replace('# on +([a-z_0-9]+) \‍(#i', ' on site_checker_\\1 (', $query);
3165 $arQuery = $DB->ParseSQLBatch(str_replace("\r", "", $query));
3166 foreach ($arQuery as $sql)
3167 {
3168 if (!$DB->Query($sql, true))
3169 {
3170 break;
3171 }
3172 }
3173 }
3174
3175 foreach ($arTables as $table => $sql)
3176 {
3177 $arIndexes = [];
3178 $rs = $DB->Query('SHOW INDEXES FROM ' . $DB->quote($table));
3179 while ($f = $rs->Fetch())
3180 {
3181 $column = strtolower($f['Column_name'] . ($f['Sub_part'] ? '(' . $f['Sub_part'] . ')' : ''));
3182 if (!empty($arIndexes[$f['Key_name']]))
3183 {
3184 $arIndexes[$f['Key_name']] .= ',' . $column;
3185 }
3186 else
3187 {
3188 $arIndexes[$f['Key_name']] = $column;
3189 }
3190 }
3191
3192 $tmp_table = 'site_checker_' . $table;
3193 $arIndexes_tmp = [];
3194 $arFT = [];
3195 $arUnique = [];
3196 $rs = $DB->Query('SHOW INDEXES FROM ' . $DB->quote($tmp_table));
3197 while ($f = $rs->Fetch())
3198 {
3199 $column = strtolower($f['Column_name'] . ($f['Sub_part'] ? '(' . $f['Sub_part'] . ')' : ''));
3200 if (!empty($arIndexes_tmp[$f['Key_name']]))
3201 {
3202 $arIndexes_tmp[$f['Key_name']] .= ',' . $column;
3203 }
3204 else
3205 {
3206 $arIndexes_tmp[$f['Key_name']] = $column;
3207 }
3208 if ($f['Index_type'] == 'FULLTEXT')
3209 {
3210 $arFT[$f['Key_name']] = true;
3211 }
3212 if ($f['Non_unique'] == 0)
3213 {
3214 $arUnique[$f['Key_name']] = true;
3215 }
3216 }
3217
3218 foreach ($arIndexes_tmp as $name => $ix)
3219 {
3220 if (!in_array($ix, $arIndexes))
3221 {
3222 if (!empty($arIndexes[$name]))
3223 {
3224 if ($name == 'PRIMARY') // dropping primary is not supported
3225 {
3226 continue;
3227 }
3228
3229 $sql = 'ALTER TABLE ' . $DB->quote($table) . ' DROP INDEX ' . $DB->quote($name);
3230 if ($this->fix_mode)
3231 {
3232 if (!$DB->Query($sql, true))
3233 {
3234 return $this->Result(false, 'Mysql Query Error: ' . $sql . ' [' . $DB->db_Error . ']');
3235 }
3236 }
3237 else
3238 {
3239 Application::getInstance()->getSession()['FixQueryList'][] = $sql;
3240 $this->arTestVars['iError'] = ($this->arTestVars['iError'] ?? 0) + 1;
3241 $this->arTestVars['iErrorAutoFix'] = ($this->arTestVars['iErrorAutoFix'] ?? 0) + 1;
3242 }
3243 }
3244 }
3245 }
3246
3247 $arColumns = [];
3248 $rs = $DB->Query('SHOW COLUMNS FROM ' . $DB->quote($table));
3249 while ($f = $rs->Fetch())
3250 {
3251 $arColumns[strtolower($f['Field'])] = $f;
3252 }
3253
3254 $rs = $DB->Query('SHOW COLUMNS FROM ' . $DB->quote($tmp_table));
3255 while ($f_tmp = $rs->Fetch())
3256 {
3257 $tmp = TableFieldConstruct($f_tmp);
3258 if (isset($arColumns[strtolower($f_tmp['Field'])]))
3259 {
3260 $f = $arColumns[strtolower($f_tmp['Field'])];
3261 if (($cur = TableFieldConstruct($f)) != $tmp)
3262 {
3263 $sql = 'ALTER TABLE ' . $DB->quote($table) . ' CHANGE ' . $DB->quote($f['Field']) . ' ' . $tmp;
3264 if ($this->fix_mode)
3265 {
3266 if ($this->TableFieldCanBeAltered($f, $f_tmp))
3267 {
3268 if (!$DB->Query($sql, true))
3269 {
3270 return $this->Result(false, 'Mysql Query Error: ' . $sql . ' [' . $DB->db_Error . ']');
3271 }
3272 }
3273 else
3274 {
3275 $this->arTestVars['iErrorFix'] = ($this->arTestVars['iErrorFix'] ?? 0) + 1;
3276 }
3277 }
3278 else
3279 {
3280 Application::getInstance()->getSession()['FixQueryList'][] = $sql;
3281 $strError .= GetMessage('SC_ERR_FIELD_DIFFERS', ['#TABLE#' => $table, '#FIELD#' => $f['Field'], '#CUR#' => $cur, '#NEW#' => $tmp]) . "<br>";
3282 $this->arTestVars['iError'] = ($this->arTestVars['iError'] ?? 0) + 1;
3283 if ($this->TableFieldCanBeAltered($f, $f_tmp))
3284 {
3285 $this->arTestVars['iErrorAutoFix'] = ($this->arTestVars['iErrorAutoFix'] ?? 0) + 1;
3286 }
3287 $this->arTestVars['cntDiffFields'] = ($this->arTestVars['cntDiffFields'] ?? 0) + 1;
3288 }
3289 }
3290 }
3291 else
3292 {
3293 $sql = 'ALTER TABLE ' . $DB->quote($table) . ' ADD ' . preg_replace('#auto_increment#i', '', $tmp); // if only Primary Key is missing we will have to pass the test twice
3294 if ($this->fix_mode)
3295 {
3296 if (!$DB->Query($sql, true))
3297 {
3298 return $this->Result(false, 'Mysql Query Error: ' . $sql . ' [' . $DB->db_Error . ']');
3299 }
3300 }
3301 else
3302 {
3303 Application::getInstance()->getSession()['FixQueryList'][] = $sql;
3304 $strError .= GetMessage('SC_ERR_NO_FIELD', ['#TABLE#' => $table, '#FIELD#' => $f_tmp['Field']]) . "<br>";
3305 $this->arTestVars['iError'] = ($this->arTestVars['iError'] ?? 0) + 1;
3306 $this->arTestVars['iErrorAutoFix'] = ($this->arTestVars['iErrorAutoFix'] ?? 0) + 1;
3307 $this->arTestVars['cntNoFields'] = ($this->arTestVars['cntNoFields'] ?? 0) + 1;
3308 }
3309 }
3310 }
3311
3312 foreach ($arIndexes_tmp as $name => $ix)
3313 {
3314 if (!in_array($ix, $arIndexes))
3315 {
3316 if ($name == 'PRIMARY' && $arIndexes['PRIMARY']) // Primary key exists
3317 {
3318 $this->arTestVars['iError'] = ($this->arTestVars['iError'] ?? 0) + 1;
3319 $strError .= GetMessage('SC_ERR_NO_INDEX', ['#TABLE#' => $table, '#INDEX#' => $name . ' (' . $ix . ')']) . "<br>";
3320 continue;
3321 }
3322
3323 if ($name == 'PRIMARY')
3324 {
3325 $sql = 'ALTER TABLE ' . $DB->quote($table) . ' ADD PRIMARY KEY (' . $ix . ')';
3326 }
3327 else
3328 {
3329 $indexType = '';
3330 if (!empty($arFT[$name]))
3331 {
3332 $indexType = 'FULLTEXT ';
3333 }
3334 elseif (!empty($arUnique[$name]))
3335 {
3336 $indexType = 'UNIQUE ';
3337 }
3338 $sql = 'CREATE ' . $indexType . 'INDEX ' . $DB->quote($name) . ' ON ' . $DB->quote($table) . ' (' . $ix . ')';
3339 }
3340 if ($this->fix_mode)
3341 {
3342 if (!$DB->Query($sql, true))
3343 {
3344 return $this->Result(false, 'Mysql Query Error: ' . $sql . ' [' . $DB->db_Error . ']');
3345 }
3346 }
3347 else
3348 {
3349 Application::getInstance()->getSession()['FixQueryList'][] = $sql;
3350 $strError .= GetMessage('SC_ERR_NO_INDEX', ['#TABLE#' => $table, '#INDEX#' => $name . ' (' . $ix . ')']) . "<br>";
3351 $this->arTestVars['iError'] = ($this->arTestVars['iError'] ?? 0) + 1;
3352 $this->arTestVars['iErrorAutoFix'] = ($this->arTestVars['iErrorAutoFix'] ?? 0) + 1;
3353 $this->arTestVars['cntNoIndexes'] = ($this->arTestVars['cntNoIndexes'] ?? 0) + 1;
3354 }
3355 }
3356 }
3357
3358 $DB->Query('DROP TABLE ' . $DB->quote($tmp_table));
3359 }
3360
3361 echo $strError; // to log
3362 }
3363
3364 if ($iCurrent < $cnt) // partial
3365 {
3366 $this->arTestVars['last_value'] = $module;
3367 $this->test_percent = floor($iCurrent / $cnt * 100);
3368 return true;
3369 }
3370
3371 if ($this->fix_mode)
3372 {
3373 if (!empty($this->arTestVars['iErrorFix']))
3374 {
3375 return $this->Result(null, GetMessage('SC_CHECK_TABLES_STRUCT_ERRORS_FIX',
3376 [
3377 '#VAL#' => intval($this->arTestVars['iErrorFix']),
3378 ]));
3379 }
3380 }
3381 else
3382 {
3383 if (isset($this->arTestVars['iError']) && $this->arTestVars['iError'] > 0)
3384 {
3385 if (is_array(Application::getInstance()->getSession()['FixQueryList']) && count(Application::getInstance()->getSession()['FixQueryList']))
3386 {
3387 echo implode(";\n", Application::getInstance()->getSession()['FixQueryList']) . ';';
3388 }
3389 Application::getInstance()->getSession()['FixQueryList'] = [];
3390 return $this->Result(
3391 false,
3392 GetMessage('SC_CHECK_TABLES_STRUCT_ERRORS', [
3393 '#VAL#' => intval($this->arTestVars['iError'] ?? 0),
3394 '#VAL1#' => intval($this->arTestVars['iErrorAutoFix'] ?? 0),
3395 '#NO_TABLES#' => intval($this->arTestVars['cntNoTables'] ?? 0),
3396 '#NO_FIELDS#' => intval($this->arTestVars['cntNoFields'] ?? 0),
3397 '#DIFF_FIELDS#' => intval($this->arTestVars['cntDiffFields'] ?? 0),
3398 '#NO_INDEXES#' => intval($this->arTestVars['cntNoIndexes'] ?? 0),
3399 '#NO_VALUES#' => intval($this->arTestVars['cntNoValues'] ?? 0),
3400 ]) . (!empty($this->arTestVars['iErrorAutoFix']) ? fix_link(3) : '')
3401 );
3402 }
3403 }
3404 return true;
3405 }
3406 ###############
3407 # }
3408 #
3409
3410 public static function CommonTest()
3411 {
3412 if (
3413 defined('BX_CRONTAB')
3414 || (defined('CHK_EVENT') && CHK_EVENT === true)
3415 || (!isset($_SERVER['HTTP_HOST']) || !$_SERVER['HTTP_HOST'])
3416 )
3417 {
3418 // can't get real HTTP server vars from cron
3419 return "CSiteCheckerTest::CommonTest();";
3420 }
3421
3422 if (
3423 ($ntlm_varname = COption::GetOptionString('ldap', 'ntlm_varname', 'REMOTE_USER'))
3424 && (trim($_SERVER[$ntlm_varname] ?? ''))
3425 )
3426 {
3427 // Server NTLM is enabled, no way to connect through a socket
3428 return "CSiteCheckerTest::CommonTest();";
3429 }
3430
3431 IncludeModuleLangFile($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/admin/site_checker.php');
3432
3433 $step = 0;
3434 $ar = null;
3435 $success = true;
3436 while (true)
3437 {
3438 $oTest = new CSiteCheckerTest($step, 1);
3439 if ($ar !== null)
3440 {
3441 $oTest->arTestVars = $ar;
3442 }
3443 $oTest->ssl =
3444 (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
3445 || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
3446 || (isset($_SERVER["SERVER_PORT"]) && $_SERVER["SERVER_PORT"] == 443);
3447
3448 if (preg_match('#^(.+):([0-9]+)$#', $_SERVER['HTTP_HOST'], $regs))
3449 {
3450 $oTest->host = $regs[1];
3451 $oTest->port = $regs[2];
3452 if ($oTest->port == 443)
3453 {
3454 $oTest->ssl = true;
3455 }
3456 }
3457 else
3458 {
3459 $oTest->host = $_SERVER['HTTP_HOST'];
3460 $oTest->port = isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] ? $_SERVER['SERVER_PORT'] : ($oTest->ssl ? 443 : 80);
3461 }
3462 $oTest->Start();
3463 if ($oTest->result === false)
3464 {
3465 $error = [
3466 "MESSAGE" =>
3467 (
3468 IsModuleInstalled('intranet') ?
3469 GetMessage("MAIN_SC_GOT_ERRORS", ['#LINK#' => "/bitrix/admin/site_checker.php?lang=" . LANGUAGE_ID . "&express_test=Y"]) :
3470 GetMessage("MAIN_SC_SITE_GOT_ERRORS", ['#LINK#' => "/bitrix/admin/site_checker.php?lang=" . LANGUAGE_ID . "&start_test=Y"])
3471 ),
3472 "TAG" => "SITE_CHECKER",
3473 "MODULE_ID" => "MAIN",
3474 'NOTIFY_TYPE' => CAdminNotify::TYPE_NORMAL,
3475 ];
3477
3478 $success = false;
3479 break;
3480 }
3481
3482 if ($oTest->percent >= 100)
3483 {
3484 break;
3485 }
3486
3487 $step++;
3488
3489 $ar = $oTest->arTestVars;
3490 }
3491
3492 $REMOTE_ADDR = $_SERVER['REMOTE_ADDR'];
3493 $HTTP_USER_AGENT = $_SERVER['HTTP_USER_AGENT'];
3494 $_SERVER['REMOTE_ADDR'] = '-';
3495 $_SERVER['HTTP_USER_AGENT'] = '-';
3497 "SEVERITY" => "WARNING",
3498 "AUDIT_TYPE_ID" => $success ? 'SITE_CHECKER_SUCCESS' : 'SITE_CHECKER_ERROR',
3499 "MODULE_ID" => "main",
3500 "ITEM_ID" => 'CSiteCheckerTest::CommonTest();',
3501 "URL" => '-',
3502 "DESCRIPTION" => '',
3503 ]);
3504 $_SERVER['REMOTE_ADDR'] = $REMOTE_ADDR;
3505 $_SERVER['HTTP_USER_AGENT'] = $HTTP_USER_AGENT;
3506
3507 return "CSiteCheckerTest::CommonTest();";
3508 }
3509
3510 public static function PhpTestAgent()
3511 {
3512 IncludeModuleLangFile($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/admin/site_checker.php');
3513
3514 if (version_compare($v = phpversion(), self::MIN_PHP_VER, '<'))
3515 {
3517 'MESSAGE' => GetMessage('PHP_VER_NOTIFY', ['#CUR#' => $v, '#REQ#' => self::MIN_PHP_VER]),
3518 'TAG' => 'PHP_VERSION',
3519 'MODULE_ID' => 'MAIN',
3520 'NOTIFY_TYPE' => CAdminNotify::TYPE_ERROR,
3521 ]);
3522
3523 return "CSiteCheckerTest::PhpTestAgent();";
3524 }
3525
3526 CAdminNotify::DeleteByTag('PHP_VERSION');
3527
3528 return '';
3529 }
3530}
3531
3533{
3535 public $arFail = [];
3536 public $FilesCount = 0;
3537 public $MaxFail = 9;
3538 public $TimeLimit = 0;
3539 public $SkipPath = '';
3540 public $BreakPoint = '';
3541
3542 public function __construct()
3543 {
3544 $this->StartTime = time();
3545 }
3546
3547 function Search($path)
3548 {
3549 if (time() - $this->StartTime > $this->TimeLimit)
3550 {
3551 $this->BreakPoint = $path;
3552 return empty($this->arFail);
3553 }
3554
3555 if (count($this->arFail) > $this->MaxFail)
3556 {
3557 return false;
3558 }
3559
3560 if ($this->SkipPath)
3561 {
3562 if (!str_starts_with($this->SkipPath, dirname($path)))
3563 {
3564 return null;
3565 }
3566
3567 if ($this->SkipPath == $path)
3568 {
3569 $this->SkipPath = null;
3570 }
3571 }
3572
3573 if (is_dir($path))
3574 {
3575 if (is_readable($path))
3576 {
3577 if (!is_writable($path))
3578 {
3579 $this->arFail[] = $path;
3580 }
3581
3582 if ($dir = opendir($path))
3583 {
3584 while (false !== $item = readdir($dir))
3585 {
3586 if ($item == '.' || $item == '..')
3587 {
3588 continue;
3589 }
3590
3591 $this->Search($path . '/' . $item);
3592 if ($this->BreakPoint)
3593 {
3594 break;
3595 }
3596 }
3597 closedir($dir);
3598 }
3599 }
3600 else
3601 {
3602 $this->arFail[] = $path;
3603 }
3604 }
3605 elseif (!$this->SkipPath)
3606 {
3607 $this->FilesCount++;
3608 if (!is_readable($path) || !is_writable($path))
3609 {
3610 $this->arFail[] = $path;
3611 }
3612 }
3613 return empty($this->arFail);
3614 }
3615}
3616
3621{
3622 include_once($path);
3623
3624 $arr = explode("/", $path);
3625 $i = array_search("modules", $arr);
3626 $class_name = $arr[$i + 1];
3627
3628 return CModule::CreateModuleObject($class_name);
3629}
3630
3631function IsHttpResponseSuccess($res, $strRequest)
3632{
3633 $strRes = GetHttpResponse($res, $strRequest, $strHeaders);
3634 if (trim($strRes) == 'SUCCESS')
3635 {
3636 return true;
3637 }
3638 else
3639 {
3640 PrintHTTP($strRequest, $strHeaders, $strRes);
3641 return false;
3642 }
3643}
3644
3645function GetHttpResponse($res, $strRequest, &$strHeaders)
3646{
3647 fputs($res, $strRequest);
3648
3649 $strHeaders = "";
3650 $bChunked = false;
3651 $Content_Length = false;
3652 while (!feof($res) && ($line = fgets($res, 4096)) && $line != "\r\n")
3653 {
3654 $strHeaders .= $line;
3655 if (preg_match("/Transfer-Encoding: +chunked/i", $line))
3656 {
3657 $bChunked = true;
3658 }
3659
3660 if (preg_match("/Content-Length: +([0-9]+)/i", $line, $regs))
3661 {
3662 $Content_Length = $regs[1];
3663 }
3664 }
3665
3666 $strRes = "";
3667 if ($bChunked)
3668 {
3669 $maxReadSize = 4096;
3670
3671 $line = fgets($res, $maxReadSize);
3672 $line = strtolower($line);
3673
3674 $strChunkSize = "";
3675 $i = 0;
3676 while ($i < strlen($line) && in_array($line[$i], ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"]))
3677 {
3678 $strChunkSize .= $line[$i];
3679 $i++;
3680 }
3681
3682 $chunkSize = hexdec($strChunkSize);
3683
3684 while ($chunkSize > 0)
3685 {
3686 $processedSize = 0;
3687 $readSize = (($chunkSize > $maxReadSize) ? $maxReadSize : $chunkSize);
3688
3689 while ($readSize > 0 && $line = fread($res, $readSize))
3690 {
3691 $strRes .= $line;
3692 $processedSize += strlen($line);
3693 $newSize = $chunkSize - $processedSize;
3694 $readSize = (($newSize > $maxReadSize) ? $maxReadSize : $newSize);
3695 }
3696
3697 $line = fgets($res, $maxReadSize);
3698 $line = strtolower($line);
3699
3700 $strChunkSize = "";
3701 $i = 0;
3702 while ($i < strlen($line) && in_array($line[$i], ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"]))
3703 {
3704 $strChunkSize .= $line[$i];
3705 $i++;
3706 }
3707
3708 $chunkSize = hexdec($strChunkSize);
3709 }
3710 }
3711 elseif ($Content_Length !== false)
3712 {
3713 if ($Content_Length > 0)
3714 {
3715 $strRes = fread($res, $Content_Length);
3716 }
3717 }
3718 else
3719 {
3720 while ($line = fread($res, 4096))
3721 {
3722 $strRes .= $line;
3723 }
3724 }
3725
3726 fclose($res);
3727 return $strRes;
3728}
3729
3731{
3732 $LICENSE_KEY = '';
3733 @include($_SERVER['DOCUMENT_ROOT'] . '/bitrix/license_key.php');
3734 if ($LICENSE_KEY == '')
3735 {
3736 $LICENSE_KEY = 'DEMO';
3737 }
3738 return md5($_SERVER['DOCUMENT_ROOT'] . filemtime($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/admin/site_checker.php') . $LICENSE_KEY);
3739}
3740
3741function getCharsetByCollation($collation)
3742{
3743 global $DB;
3744 static $CACHE;
3745 if (!$c = &$CACHE[$collation])
3746 {
3747 $res0 = $DB->Query('SHOW COLLATION LIKE "' . $collation . '"');
3748 $f0 = $res0->Fetch();
3749 $c = $f0['Charset'];
3750 }
3751 return $c;
3752}
3753
3754function InitPureDB()
3755{
3756 require_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/bx_root.php");
3757 require_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/lib/loader.php");
3758 require_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/autoload.php");
3759 require_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/tools.php");
3760
3761 global $DB, $DBDebug, $DBDebugToFile;
3762
3768 require_once $_SERVER["DOCUMENT_ROOT"] . getLocalPath('php_interface/dbconn.php', BX_PERSONAL_ROOT);
3769
3770 require_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/constants.php");
3771
3772 // Database-dependent classes
3774
3775 $DB = new CDatabase;
3776 $DB->debug = $DBDebug;
3777 $DB->DebugToFile = $DBDebugToFile;
3778
3779 if (!$DB->DoConnect())
3780 {
3782 die();
3783 }
3784}
3785
3786function TableFieldConstruct($field)
3787{
3788 global $DB;
3789
3790 $tmp = $DB->quote($field['Field']) . ' ';
3791
3792 if (preg_match("/^(TINYINT|SMALLINT|MEDIUMINT|INT|BIGINT)\\(\d+\\)(.*)/i", $field['Type'], $matches))
3793 {
3794 // As of MySQL 8.0.17, the ZEROFILL attribute is deprecated for numeric data types, as is the display width attribute for integer data types
3795 $tmp .= $matches[1] . $matches[2];
3796 }
3797 else
3798 {
3799 $tmp .= $field['Type'];
3800 }
3801
3802 if ($field['Null'] == 'YES')
3803 {
3804 $tmp .= ' NULL';
3805 }
3806 else
3807 {
3808 $tmp .= ' NOT NULL';
3809 }
3810
3811 if ($field['Default'] === null)
3812 {
3813 if ($field['Null'] == 'YES')
3814 {
3815 $tmp .= ' DEFAULT NULL ';
3816 }
3817 }
3818 else
3819 {
3820 $tmp .= ' DEFAULT ';
3821 if (($field['Type'] == 'timestamp' || $field['Type'] == 'datetime') && !preg_match('#^\d{4}#', $field['Default']))
3822 {
3823 $tmp .= $field['Default'];
3824 }
3825 elseif ($field['Type'] == 'text' && preg_match("/^'.*'$/", $field['Default']))
3826 {
3827 // MariaDB's bug with text fields default values in single quotes
3828 $tmp .= $field['Default'];
3829 }
3830 else
3831 {
3832 $tmp .= "'" . $DB->ForSQL($field['Default']) . "'";
3833 }
3834 }
3835
3836 $tmp .= ' ' . str_ireplace('DEFAULT_GENERATED', '', $field['Extra']);
3837
3838 return trim($tmp);
3839}
3840
3841function fix_link($mode = 2)
3842{
3843 return ' <a href="javascript:show_popup(\'' . GetMessageJS('SC_FIX_DATABASE') . '\', \'?fix_mode=' . $mode . '\', \'' . GetMessageJS('SC_FIX_DATABASE_CONFIRM') . '\')">' . GetMessage('SC_FIX') . '</a>';
3844}
3845
3846function PrintHTTP($strRequest, $strHeaders, $strRes)
3847{
3848 echo
3849 "== Request ==\n" .
3850 (($l = strlen($strRequest)) > 1000 ? substr($strRequest, 0, 1000) . ' ... (' . $l . ' bytes)' : $strRequest) . "\n" .
3851 "== Response ==\n" .
3852 $strHeaders . "\n" .
3853 "== Body ==\n" .
3854 (($l = strlen($strRes)) > 1000 ? substr($strRes, 0, 1000) . ' ... (' . $l . ' bytes)' : $strRes) . "\n" .
3855 "==========\n";
3856}
$path
Определения access_edit.php:21
$connection
Определения actionsdefinitions.php:38
$count
Определения admin_tab.php:4
if(empty( $fields)) foreach($fields as $field) $channelId
Определения push.php:23
static getInt(string $param)
Определения ini.php:13
static getMailEol()
Определения mail.php:856
static getList(array $parameters=array())
Определения datamanager.php:431
static getPublicLicenseCode()
Определения client.php:184
static getLongPollingUrl()
Определения config.php:80
const TYPE_ERROR
Определения admin_notify.php:8
const TYPE_NORMAL
Определения admin_notify.php:7
static Add($arFields)
Определения admin_notify.php:22
static DeleteByTag($tagId)
Определения admin_notify.php:146
static showConnectionError()
Определения database.php:156
static registerAutoload(?string $connectionType=null)
Определения database.php:952
Определения punycode.php:4
static Add($arFields)
Определения event_log.php:44
static GetList($arOrder=Array(), $arFilter=Array())
Определения ldap_server.php:19
static Send($channelId, $message, $options=array())
Определения pull_channel.php:386
static SignChannel($channelId)
Определения pull_channel.php:179
Определения site_checker.php:3533
__construct()
Определения site_checker.php:3542
Search($path)
Определения site_checker.php:3547
$StartTime
Определения site_checker.php:3534
$SkipPath
Определения site_checker.php:3539
$MaxFail
Определения site_checker.php:3537
$TimeLimit
Определения site_checker.php:3538
$arFail
Определения site_checker.php:3535
$BreakPoint
Определения site_checker.php:3540
$FilesCount
Определения site_checker.php:3536
Определения site_checker.php:8
ConnectToHost($host=false, $port=false, $ssl=false)
Определения site_checker.php:415
$LogFile
Определения site_checker.php:34
const MIN_PHP_VER
Определения site_checker.php:9
$percent
Определения site_checker.php:12
$ssl
Определения site_checker.php:30
$result
Определения site_checker.php:16
$LogResult
Определения site_checker.php:18
check_cache()
Определения site_checker.php:2016
check_method_exists()
Определения site_checker.php:2277
check_pgsql_version()
Определения site_checker.php:2314
check_socket_ssl()
Определения site_checker.php:901
$arTest
Определения site_checker.php:32
$strCurrentTestName
Определения site_checker.php:14
check_push_bitrix()
Определения site_checker.php:1684
check_php_settings()
Определения site_checker.php:553
check_ntlm()
Определения site_checker.php:968
check_bx_crontab()
Определения site_checker.php:2290
check_pgsql_db_charset()
Определения site_checker.php:2332
$group_desc
Определения site_checker.php:20
$strResult
Определения site_checker.php:24
check_mysql_table_status()
Определения site_checker.php:2479
check_server_vars()
Определения site_checker.php:669
check_mysql_bug_version()
Определения site_checker.php:2388
static CommonTest()
Определения site_checker.php:3410
check_mysql_db_charset()
Определения site_checker.php:2588
check_php_modules()
Определения site_checker.php:501
check_mbstring()
Определения site_checker.php:1269
check_connect_mail()
Определения site_checker.php:745
check_fast_download()
Определения site_checker.php:1831
check_post()
Определения site_checker.php:1124
check_mysql_mode()
Определения site_checker.php:2412
check_mail_push()
Определения site_checker.php:787
Start()
Определения site_checker.php:279
check_mail($big=false)
Определения site_checker.php:687
check_mysql_time()
Определения site_checker.php:2460
check_session()
Определения site_checker.php:1214
check_mysql_table_format()
Определения site_checker.php:2652
$strError
Определения site_checker.php:22
check_exec()
Определения site_checker.php:2030
check_search()
Определения site_checker.php:1793
check_mysql_connection_charset()
Определения site_checker.php:2540
check_pull_comments()
Определения site_checker.php:1617
$host
Определения site_checker.php:29
OpenLog()
Определения site_checker.php:405
__construct($step=0, $fast=0, $fix_mode=0)
Определения site_checker.php:36
$arTestVars
Определения site_checker.php:11
check_socket()
Определения site_checker.php:857
check_ad()
Определения site_checker.php:954
check_socnet()
Определения site_checker.php:759
$timeout
Определения site_checker.php:23
check_session_ua()
Определения site_checker.php:1233
$step
Определения site_checker.php:25
Result($result, $text='')
Определения site_checker.php:373
check_install_scripts()
Определения site_checker.php:2090
$strNextTestName
Определения site_checker.php:15
check_rest()
Определения site_checker.php:778
check_security()
Определения site_checker.php:2061
check_access_mobile()
Определения site_checker.php:1859
check_pgsql_connection_charset()
Определения site_checker.php:2355
check_mysql_table_charset()
Определения site_checker.php:2714
check_ca_file()
Определения site_checker.php:989
$port
Определения site_checker.php:31
check_mysql_table_structure()
Определения site_checker.php:2958
static GetTestList()
Определения site_checker.php:266
check_sites()
Определения site_checker.php:2206
check_upload_raw()
Определения site_checker.php:1119
check_turn()
Определения site_checker.php:1633
Unformat($str)
Определения site_checker.php:450
check_memory_limit()
Определения site_checker.php:1147
$test_percent
Определения site_checker.php:21
$force_repair
Определения site_checker.php:28
$last_function
Определения site_checker.php:13
check_extranet()
Определения site_checker.php:1744
check_webdav()
Определения site_checker.php:1753
check_upload_big()
Определения site_checker.php:1114
$fix_mode
Определения site_checker.php:26
check_pcre_recursion()
Определения site_checker.php:2257
check_perf()
Определения site_checker.php:1959
check_access_docs()
Определения site_checker.php:1735
TableFieldCanBeAltered($f, $f_tmp)
Определения site_checker.php:474
check_mail_big()
Определения site_checker.php:722
check_compression()
Определения site_checker.php:877
$cafile
Определения site_checker.php:27
$LogResourse
Определения site_checker.php:17
check_dbconn()
Определения site_checker.php:1020
check_upload($big=false, $raw=false)
Определения site_checker.php:1044
check_localredirect()
Определения site_checker.php:2141
check_getimagesize()
Определения site_checker.php:2126
static PhpTestAgent()
Определения site_checker.php:3510
check_mail_b_event()
Определения site_checker.php:727
check_pull_stream()
Определения site_checker.php:1469
$group_name
Определения site_checker.php:19
$function
Определения site_checker.php:33
global $CACHE_MANAGER
Определения clear_component_cache.php:7
$startTime
Определения sync.php:69
$str
Определения commerceml2.php:63
$f
Определения component_props.php:52
$arValues
Определения component_props.php:25
if(!is_array($prop["VALUES"])) $tmp
Определения component_props.php:203
$new
Определения file_edit.php:48
$arr
Определения file_new.php:624
<? if( $useEditor3):?>< tr class="heading">< td colspan="2"><? echo GetMessage("FILEMAN_OPTION_SPELL_SET");?></td ></tr ><? if(function_exists( 'pspell_config_create')):$use_pspell_checked=(COption::GetOptionString( $module_id, "use_pspell", "Y")=="Y") ? "checked" :"";?>< tr >< td valign="top">< label for="use_pspell"><?echo GetMessage("FILEMAN_OPTION_USE_PSPELL");?></label >< br >< a title="<?echo GetMessage("FILEMAN_OPTION_ADDISH_DICS_TITLE");?> http
Определения options.php:1473
$res
Определения filter_act.php:7
$_REQUEST["admin_mnu_menu_id"]
Определения get_menu.php:8
$bFound
Определения get_search.php:40
$query
Определения get_search.php:11
$region
Определения .description.php:13
const BX_SKIP_SESSION_EXPAND
Определения headers.php:2
$errors
Определения iblock_catalog_edit.php:74
$output
Определения options.php:436
$_SERVER["DOCUMENT_ROOT"]
Определения cron_frame.php:9
global $DB
Определения cron_frame.php:29
$context
Определения csv_new_setup.php:223
$success
Определения mail_entry.php:69
IsHttpResponseSuccess($res, $strRequest)
Определения site_checker.php:3631
getCharsetByCollation($collation)
Определения site_checker.php:3741
GetHttpResponse($res, $strRequest, &$strHeaders)
Определения site_checker.php:3645
PrintHTTP($strRequest, $strHeaders, $strRes)
Определения site_checker.php:3846
fix_link($mode=2)
Определения site_checker.php:3841
checker_get_unique_id()
Определения site_checker.php:3730
CheckGetModuleInfo($path)
Определения site_checker.php:3620
TableFieldConstruct($field)
Определения site_checker.php:3786
$status
Определения session.php:10
global $DBDebugToFile
Определения start.php:35
global $DBDebug
Определения start.php:35
if($NS['step']==6) if( $NS[ 'step']==7) if(COption::GetOptionInt('main', 'disk_space', 0) > 0) $info
Определения backup.php:924
CheckSerializedData($str, $max_depth=200)
Определения tools.php:4949
CheckDirPath($path)
Определения tools.php:2707
IsModuleInstalled($module_id)
Определения tools.php:5301
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
Определения tools.php:2701
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
GetMessage($name, $aReplace=null)
Определения tools.php:3397
getLocalPath($path, $baseFolder="/bitrix")
Определения tools.php:5092
GetMessageJS($name, $aReplace=false)
Определения tools.php:3392
$name
Определения menu_edit.php:35
$time
Определения payment.php:61
$var
Определения payment.php:63
if(mb_strlen($order)< 6) $desc
Определения payment.php:44
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$ar
Определения options.php:199
$dir
Определения quickway.php:303
die
Определения quickway.php:367
$text
Определения template_pdf.php:79
$i
Определения factura.php:643
$page
Определения order_form.php:33
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
$val
Определения options.php:1793
$method
Определения index.php:27
$matches
Определения index.php:22
while($arSite=$dbSites->Fetch()) $oAuthManager
Определения options.php:26
$error
Определения subscription_card_product.php:20
$rs
Определения action.php:82
$k
Определения template_pdf.php:567
$max
Определения template_copy.php:262
$url
Определения iframe.php:7
$site
Определения yandex_run.php:614