wiki:xref:dokuwiki:inc:init.php
- init.php
<?php 2 3 /** 4 * Инициализируйте некоторые значения по умолчанию, необходимые для DokuWiki 5 */ 6 7 use dokuwiki\Extension\PluginController; 8 use dokuwiki\ErrorHandler; 9 use dokuwiki\Input\Input; 10 use dokuwiki\Extension\Event; 11 use dokuwiki\Extension\EventHandler; 12 13 /** 14 * время выполнения Dokuwiki 15 * 16 * @param целое число $ начало 17 * 18 * @return смешанный 19 */ 20 function delta_time($start = 0) 21 { 22 return microtime(true) - ((float)$start); 23 } 24 define('DOKU_START_TIME', delta_time()); 25 26 global $config_cascade; 27 $config_cascade = []; 28 29 // если доступно, загрузите файл конфигурации предварительной загрузки 30 $preload = fullpath(__DIR__) . '/preload.php'; 31 if (file_exists($preload)) include($preload); 32 33 // определить путь включения 34 if (!defined('DOKU_INC')) define('DOKU_INC', fullpath(__DIR__ . '/../') . '/'); 35 36 // определить каталог плагина 37 if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/'); 38 39 // определить путь конфигурации (упаковщики могут захотеть изменить его на / etc / dokuwiki /) 40 if (!defined('DOKU_CONF')) define('DOKU_CONF', DOKU_INC . 'conf/'); 41 42 // проверьте переопределение сообщений об ошибках или установите для сообщений об ошибках разумные значения 43 if (!defined('DOKU_E_LEVEL') && file_exists(DOKU_CONF . 'report_e_all')) { 44 define('DOKU_E_LEVEL', E_ALL); 45 } 46 if (!defined('DOKU_E_LEVEL')) { 47 error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED); 48 } else { 49 error_reporting(DOKU_E_LEVEL); 50 } 51 52 // избегайте проблем с кэшированием #1594 53 header('Vary: Cookie'); 54 55 // инициализация кэшей памяти 56 global $cache_revinfo; 57 $cache_revinfo = []; 58 global $cache_wikifn; 59 $cache_wikifn = []; 60 global $cache_cleanid; 61 $cache_cleanid = []; 62 global $cache_authname; 63 $cache_authname = []; 64 global $cache_metadata; 65 $cache_metadata = []; 66 67 // всегда включайте ' inc / config_cascade.php ' 68 // ранее заданные в preload.php поля $config_cascade будут объединены со значениями по умолчаниюs 69 include(DOKU_INC . 'inc/config_cascade.php'); 70 71 //подготовить массив конфигурации() 72 global $conf; 73 $conf = []; 74 75 // загрузить глобальный файл(ы) конфигурации 76 foreach (['default', 'local', 'protected'] as $config_group) { 77 if (empty($config_cascade['main'][$config_group])) continue; 78 foreach ($config_cascade['main'][$config_group] as $config_file) { 79 if (file_exists($config_file)) { 80 include($config_file); 81 } 82 } 83 } 84 85 //подготовить массив лицензий() 86 global $license; 87 $license = []; 88 89 // загрузить файл(ы) лицензии 90 foreach (['default', 'local'] as $config_group) { 91 if (empty($config_cascade['license'][$config_group])) continue; 92 foreach ($config_cascade['license'][$config_group] as $config_file) { 93 if (file_exists($config_file)) { 94 include($config_file); 95 } 96 } 97 } 98 99 // установить часовой пояс (как в днях до 5.3.0) 100 date_default_timezone_set(@date_default_timezone_get()); 101 102 // определить baseURL 103 if (!defined('DOKU_REL')) define('DOKU_REL', getBaseURL(false)); 104 if (!defined('DOKU_URL')) define('DOKU_URL', getBaseURL(true)); 105 if (!defined('DOKU_BASE')) { 106 if ($conf['canonical']) { 107 define('DOKU_BASE', DOKU_URL); 108 } else { 109 define('DOKU_BASE', DOKU_REL); 110 } 111 } 112 113 // определяем пробелы 114 if (!defined('NL')) define('NL', "\n"); 115 if (!defined('DOKU_LF')) define('DOKU_LF', "\n"); 116 if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t"); 117 118 // определить cookie и идентификатор сеанса, добавить порт сервера, если настроен securecookie FS#1664 119 if (!defined('DOKU_COOKIE')) { 120 $serverPort = $_SERVER['SERVER_PORT'] ?? ''; 121 define('DOKU_COOKIE', 'DW' . md5(DOKU_REL . (($conf['securecookie']) ? $serverPort : ''))); 122 unset($serverPort); 123 } 124 125 // определить основной скрипт 126 if (!defined('DOKU_SCRIPT')) define('DOKU_SCRIPT', 'doku.php'); 127 128 if (!defined('DOKU_TPL')) { 129 /** 130 * @deprecated 2012-10-13 заменен более динамичным методом 131 * @see tpl_basedir() 132 */ 133 define('DOKU_TPL', DOKU_BASE . 'lib/tpl/' . $conf['template'] . '/'); 134 } 135 136 if (!defined('DOKU_TPLINC')) { 137 /** 138 * @deprecated 2012-10-13 replaced by more dynamic method 139 * @see tpl_incdir() 140 */ 141 define('DOKU_TPLINC', DOKU_INC . 'lib/tpl/' . $conf['template'] . '/'); 142 } 143 144 // сделать перезапись сеанса XHTML-совместимой 145 @ini_set('arg_separator.output', '&'); 146 147 // убедитесь, что глобальная zlib не мешает FS#1132 148 @ini_set('zlib.output_compression', 'off'); 149 150 // увеличить предел возврата PCRE 151 @ini_set('pcre.backtrack_limit', '20971520'); 152 153 // включить сжатие gzip, если поддерживается 154 $httpAcceptEncoding = $_SERVER['HTTP_ACCEPT_ENCODING'] ?? ''; 155 $conf['gzip_output'] &= (strpos($httpAcceptEncoding, 'gzip') !== false); 156 global $ACT; 157 if ( 158 $conf['gzip_output'] && 159 !defined('DOKU_DISABLE_GZIP_OUTPUT') && 160 function_exists('ob_gzhandler') && 161 // Disable compression when a (compressed) sitemap might be delivered 162 // See https://bugs.dokuwiki.org/index.php?do=details&task_id=2576 163 $ACT != 'sitemap' 164 ) { 165 ob_start('ob_gzhandler'); 166 } 167 168 // инициализация сеанса 169 if (!headers_sent() && !defined('NOSESSION')) { 170 if (!defined('DOKU_SESSION_NAME')) define('DOKU_SESSION_NAME', "DokuWiki"); 171 if (!defined('DOKU_SESSION_LIFETIME')) define('DOKU_SESSION_LIFETIME', 0); 172 if (!defined('DOKU_SESSION_PATH')) { 173 $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir']; 174 define('DOKU_SESSION_PATH', $cookieDir); 175 } 176 if (!defined('DOKU_SESSION_DOMAIN')) define('DOKU_SESSION_DOMAIN', ''); 177 178 // начать сеанс 179 init_session(); 180 181 // загрузить оставшиеся сообщения 182 if (isset($_SESSION[DOKU_COOKIE]['msg'])) { 183 $MSG = $_SESSION[DOKU_COOKIE]['msg']; 184 unset($_SESSION[DOKU_COOKIE]['msg']); 185 } 186 } 187 188 // не позволяйте куки-файлам вмешиваться в переменные запроса 189 $_REQUEST = array_merge($_GET, $_POST); 190 191 // мы не хотим, чтобы URL-адрес очистки был выкопан 192 if (isset($_REQUEST['purge']) && !empty($_SERVER['HTTP_REFERER'])) unset($_REQUEST['purge']); 193 194 // предварительно рассчитать режимы создания файла 195 init_creationmodes(); 196 197 // создаем реальные пути и проверяем их 198 init_paths(); 199 init_files(); 200 201 // настройка класса контроллера плагина (можно перезаписать в preload.php ) 202 global $plugin_controller_class, $plugin_controller; 203 if (empty($plugin_controller_class)) $plugin_controller_class = PluginController::class; 204 205 // автозагрузчик 206 require_once(DOKU_INC . 'inc/load.php'); 207 208 // отныне все является исключением 209 ErrorHandler::register(); 210 211 // отключаем gzip, если недоступно 212 define('DOKU_HAS_BZIP', function_exists('bzopen')); 213 define('DOKU_HAS_GZIP', function_exists('gzopen')); 214 if ($conf['compression'] == 'bz2' && !DOKU_HAS_BZIP) { 215 $conf['compression'] = 'gz'; 216 } 217 if ($conf['compression'] == 'gz' && !DOKU_HAS_GZIP) { 218 $conf['compression'] = 0; 219 } 220 221 // класс обработки входных данных 222 global $INPUT; 223 $INPUT = new Input(); 224 225 // инициализируем контроллер плагина 226 $plugin_controller = new $plugin_controller_class(); 227 228 // инициализируем обработчик событий 229 global $EVENT_HANDLER; 230 $EVENT_HANDLER = new EventHandler(); 231 232 $local = $conf['lang']; 233 Event::createAndTrigger('INIT_LANG_LOAD', $local, 'init_lang', true); 234 235 236 // настройка системы аутентификации 237 if (!defined('NOSESSION')) { 238 auth_setup(); 239 } 240 241 // настройка почтовой системы 242 mail_setup(); 243 244 $nil = null; 245 Event::createAndTrigger('DOKUWIKI_INIT_DONE', $nil, null, false); 246 247 /** 248 * Инициализирует сеанс 249 * 250 * Проверяет, что переданный сеансовый cookie-файл действителен, недействительные игнорируются, и выдается новый идентификатор сеанса 251 * 252 * @ссылка http://stackoverflow.com/a/33024310/172068 253 * @ссылка http://php.net/manual/en/session.configuration.php#ini.session.sid-length 254 */ 255 function init_session() 256 { 257 global $conf; 258 session_name(DOKU_SESSION_NAME); 259 session_set_cookie_params([ 260 'lifetime' => DOKU_SESSION_LIFETIME, 261 'path' => DOKU_SESSION_PATH, 262 'domain' => DOKU_SESSION_DOMAIN, 263 'secure' => ($conf['securecookie'] && is_ssl()), 264 'httponly' => true, 265 'samesite' => 'Lax', 266 ]); 267 268 // make sure the session cookie contains a valid session ID 269 if (isset($_COOKIE[DOKU_SESSION_NAME]) && !preg_match('/^[-,a-zA-Z0-9]{22,256}$/', $_COOKIE[DOKU_SESSION_NAME])) { 270 unset($_COOKIE[DOKU_SESSION_NAME]); 271 } 272 273 session_start(); 274 } 275 276 277 /** 278 * Проверяет пути из файла конфигурации 279 */ 280 function init_paths() 281 { 282 global $conf; 283 284 $paths = [ 285 'datadir' => 'pages', 286 'olddir' => 'attic', 287 'mediadir' => 'media', 288 'mediaolddir' => 'media_attic', 289 'metadir' => 'meta', 290 'mediametadir' => 'media_meta', 291 'cachedir' => 'cache', 292 'indexdir' => 'index', 293 'lockdir' => 'locks', 294 'tmpdir' => 'tmp', 295 'logdir' => 'log', 296 ]; 297 298 foreach ($paths as $c => $p) { 299 $path = empty($conf[$c]) ? $conf['savedir'] . '/' . $p : $conf[$c]; 300 $conf[$c] = init_path($path); 301 if (empty($conf[$c])) { 302 $path = fullpath($path); 303 nice_die("The $c ('$p') at $path is not found, isn't accessible or writable. 304 You should check your config and permission settings. 305 Or maybe you want to <a href=\"install.php\">run the 306 installer</a>?"); 307 } 308 } 309 310 // путь к старому списку изменений нужен только для обновления 311 $conf['changelog_old'] = init_path( 312 $conf['changelog'] ?? $conf['savedir'] . '/changes.log' 313 ); 314 if ($conf['changelog_old'] == '') { 315 unset($conf['changelog_old']); 316 } 317 // жестко запрограммирован журнал изменений, поскольку теперь это кэш, который находится в метаданных 318 $conf['changelog'] = $conf['metadir'] . '/_dokuwiki.changes'; 319 $conf['media_changelog'] = $conf['metadir'] . '/_media.changes'; 320 } 321 322 /** 323 * Загрузить языковые строки 324 * 325 * @param string $langCode код языка, переданный обработчиком событий 326 */ 327 function init_lang($langCode) 328 { 329 //подготовить языковой массив 330 global $lang, $config_cascade; 331 $lang = []; 332 333 //загрузить языковые файлы 334 require(DOKU_INC . 'inc/lang/en/lang.php'); 335 foreach ($config_cascade['lang']['core'] as $config_file) { 336 if (file_exists($config_file . 'en/lang.php')) { 337 include($config_file . 'en/lang.php'); 338 } 339 } 340 341 if ($langCode && $langCode != 'en') { 342 if (file_exists(DOKU_INC . "inc/lang/$langCode/lang.php")) { 343 require(DOKU_INC . "inc/lang/$langCode/lang.php"); 344 } 345 foreach ($config_cascade['lang']['core'] as $config_file) { 346 if (file_exists($config_file . "$langCode/lang.php")) { 347 include($config_file . "$langCode/lang.php"); 348 } 349 } 350 } 351 } 352 353 /** 354 * Проверяет наличие определенных файлов и создает их, если они отсутствуют. 355 */ 356 function init_files() 357 { 358 global $conf; 359 360 $files = [$conf['indexdir'] . '/page.idx']; 361 362 foreach ($files as $file) { 363 if (!file_exists($file)) { 364 $fh = @fopen($file, 'a'); 365 if ($fh) { 366 fclose($fh); 367 if ($conf['fperm']) chmod($file, $conf['fperm']); 368 } else { 369 nice_die("$file is not writable. Check your permissions settings!"); 370 } 371 } 372 } 373 } 374 375 /** 376 * Возвращает абсолютный путь 377 * 378 * Сначала проверяется указанный путь, затем DOKU_INC. 379 * Проверьте также доступность каталогов. 380 * 381 * @автор Андреас Гор <andi@splitbrain.org> 382 * 383 * @param string $ path 384 * 385 * @return bool | строка 386 */ 387 function init_path($path) 388 { 389 // проверка существования 390 $p = fullpath($path); 391 if (!file_exists($p)) { 392 $p = fullpath(DOKU_INC . $path); 393 if (!file_exists($p)) { 394 return ''; 395 } 396 } 397 398 // проверка возможности записи 399 if (!@is_writable($p)) { 400 return ''; 401 } 402 403 // проверка доступности (бит выполнения) для каталогов 404 if (@is_dir($p) && !file_exists("$p/.")) { 405 return ''; 406 } 407 408 return $p; 409 } 410 411 /** 412 * Устанавливает внутренние значения конфигурации fperm и dperm, которые, если установлены, 413 * будет использоваться для изменения разрешения вновь созданного каталога или 414 * файл с chmod. Учитывает влияние umask системы 415 * установка значений только при необходимости. 416 */ 417 function init_creationmodes() 418 { 419 global $conf; 420 421 // Устаревшая поддержка старой схемы umask / dmask 422 unset($conf['dmask']); 423 unset($conf['fmask']); 424 unset($conf['umask']); 425 426 $conf['fperm'] = false; 427 $conf['dperm'] = false; 428 429 // получить системную маску umask, вернуться к 0, если она недоступна 430 $umask = @umask(); 431 if (!$umask) $umask = 0000; 432 433 // проверка того, что автоматически устанавливается системой при создании файлаn 434 // и устанавливаем параметр fperm, если это не то, что нам нужно 435 $auto_fmode = 0666 & ~$umask; 436 if ($auto_fmode != $conf['fmode']) $conf['fperm'] = $conf['fmode']; 437 438 // проверка того, что автоматически устанавливается системой при создании каталога 439 // и устанавливаем параметр dperm, если это не то, что нам нужно. 440 $auto_dmode = 0777 & ~$umask; 441 if ($auto_dmode != $conf['dmode']) $conf['dperm'] = $conf['dmode']; 442 } 443 444 /** 445 * Возвращает полный абсолютный URL-адрес каталога, где 446 * DokuWiki установлен в (включая завершающий слеш) 447 * 448 * !! Невозможно получить доступ к значениям $_SERVER через $INPUT 449 * !! здесь, поскольку эта функция вызывается до $INPUT 450 * !! инициализировано. 451 * 452 * @автор Андреас Гор <andi@splitbrain.org> 453 * 454 * @param null | bool $ abs Вернуть абсолютный URL? (по умолчанию null — $conf['canonical']) 455 * 456 * @возвращаемая строка 457 */ 458 function getBaseURL($abs = null) 459 { 460 global $conf; 461 462 $abs ??= $conf['canonical']; 463 464 if (!empty($conf['basedir'])) { 465 $dir = $conf['basedir']; 466 } elseif (substr($_SERVER['SCRIPT_NAME'], -4) == '.php') { 467 $dir = dirname($_SERVER['SCRIPT_NAME']); 468 } elseif (substr($_SERVER['PHP_SELF'], -4) == '.php') { 469 $dir = dirname($_SERVER['PHP_SELF']); 470 } elseif ($_SERVER['DOCUMENT_ROOT'] && $_SERVER['SCRIPT_FILENAME']) { 471 $dir = preg_replace( 472 '/^' . preg_quote($_SERVER['DOCUMENT_ROOT'], '/') . '/', 473 '', 474 $_SERVER['SCRIPT_FILENAME'] 475 ); 476 $dir = dirname('/' . $dir); 477 } else { 478 $dir = ''; //возможно, это неверно, но мы предполагаем, что он в корне 479 } 480 481 $dir = str_replace('\\', '/', $dir); // исправление странного поведения WIN 482 $dir = preg_replace('#//+#', '/', "/$dir/"); // гарантируем начальные и конечные слеши 483 484 //handle script in lib/exe dir 485 $dir = preg_replace('!lib/exe/$!', '', $dir); 486 487 //handle script in lib/plugins dir 488 $dir = preg_replace('!lib/plugins/.*$!', '', $dir); 489 490 //завершить здесь для относительных URL-адресов 491 if (!$abs) return $dir; 492 493 //используйте конфигурацию, если она доступна, обрежьте все слеши в конце baseurl, чтобы избежать нескольких последовательных слешей в пути 494 if (!empty($conf['baseurl'])) return rtrim($conf['baseurl'], '/') . $dir; 495 496 //разделить заголовок хоста на хост и порт 497 if (isset($_SERVER['HTTP_HOST'])) { 498 if ( 499 (!empty($conf['trustedproxy'])) && isset($_SERVER['HTTP_X_FORWARDED_HOST']) 500 && preg_match('/' . $conf['trustedproxy'] . '/', $_SERVER['REMOTE_ADDR']) 501 ) { 502 $cur_host = $_SERVER['HTTP_X_FORWARDED_HOST']; 503 } else { 504 $cur_host = $_SERVER['HTTP_HOST']; 505 } 506 $parsed_host = parse_url('http://' . $cur_host); 507 $host = $parsed_host['host'] ?? ''; 508 $port = $parsed_host['port'] ?? ''; 509 } elseif (isset($_SERVER['SERVER_NAME'])) { 510 $parsed_host = parse_url('http://' . $_SERVER['SERVER_NAME']); 511 $host = $parsed_host['host'] ?? ''; 512 $port = $parsed_host['port'] ?? ''; 513 } else { 514 $host = php_uname('n'); 515 $port = ''; 516 } 517 518 if (!is_ssl()) { 519 $proto = 'http://'; 520 if ($port == '80') { 521 $port = ''; 522 } 523 } else { 524 $proto = 'https://'; 525 if ($port == '443') { 526 $port = ''; 527 } 528 } 529 530 if ($port !== '') $port = ':' . $port; 531 532 return $proto . $host . $port . $dir; 533 } 534 535 /** 536 * Проверьте, доступен ли сайт через HTTPS 537 * 538 * Apache оставляет ,$_SERVER['HTTPS'] пустым, когда он недоступен, IIS устанавливает его в значение «выкл.». 539 * «ложь» и «отключено» — это всего лишь предположения 540 * 541 * @returns bool true, когда SSL активен 542 */ 543 function is_ssl() 544 { 545 global $conf; 546 547 // проверяем, находимся ли мы за обратным прокси-сервером 548 if ( 549 (!empty($conf['trustedproxy'])) && isset($_SERVER['HTTP_X_FORWARDED_PROTO']) 550 && preg_match('/' . $conf['trustedproxy'] . '/', $_SERVER['REMOTE_ADDR']) 551 && ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') 552 ) { 553 return true; 554 } 555 556 if (preg_match('/^(|off|false|disabled)$/i', $_SERVER['HTTPS'] ?? 'off')) { 557 return false; 558 } 559 560 return true; 561 } 562 563 /** 564 * проверяет, что это ОС Windows 565 * @return bool 566 */ 567 function isWindows() 568 { 569 return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; 570 } 571 572 /** 573 * вывести приятное сообщение, даже если ни один стили еще не загружен. 574 * @param целое число | строка $ сообщение 575 * @param integer|string $msg 576 */ 577 function nice_die($msg) 578 { 579 echo<<<EOT 580 <!DOCTYPE html> 581 <html> 582 <head><title>DokuWiki Setup Error</title></head> 583 <body style="font-family: Arial, sans-serif"> 584 <div style="width:60%; margin: auto; background-color: #fcc; 585 border: 1px solid #faa; padding: 0.5em 1em;"> 586 <h1 style="font-size: 120%">DokuWiki Setup Error</h1> 587 <p>$msg</p> 588 </div> 589 </body> 590 </html> 591 EOT; 592 if (defined('DOKU_UNITTEST')) { 593 throw new RuntimeException('nice_die: ' . $msg); 594 } 595 exit(1); 596 } 597 598 /** 599 * Замена realpath() 600 * 601 * Эта функция ведет себя аналогично функции realpath() в PHP, но не разрешает 602 * символические ссылки или доступ к верхним каталогам 603 * 604 * @автор Андреас Гор <andi@splitbrain.org> 605 * @author <richpageau at yahoo dot co dot uk> 606 * @ссылка http://php.net/manual/en/function.realpath.php#75992 607 * 608 * @param string $ path 609 * @param bool $ существует 610 * 611 * @return bool | строка 612 */ 613 function fullpath($path, $exists = false) 614 { 615 static $run = 0; 616 $root = ''; 617 $iswin = (isWindows() || !empty($GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS'])); 618 619 // найти (неразрушаемый) корень пути - сохраняет содержимое Windows нетронутым 620 if ($path[0] == '/') { 621 $root = '/'; 622 } elseif ($iswin) { 623 // сопоставить букву диска и пути UNC 624 if (preg_match('!^([a-zA-z]:)(.*)!', $path, $match)) { 625 $root = $match[1] . '/'; 626 $path = $match[2]; 627 } elseif (preg_match('!^(\\\\\\\\[^\\\\/]+\\\\[^\\\\/]+[\\\\/])(.*)!', $path, $match)) { 628 $root = $match[1]; 629 $path = $match[2]; 630 } 631 } 632 $path = str_replace('\\', '/', $path); 633 634 // если указанный путь еще не был абсолютным, добавьте путь к скрипту и повторите попытку 635 if (!$root) { 636 $base = dirname($_SERVER['SCRIPT_FILENAME']); 637 $path = $base . '/' . $path; 638 if ($run == 0) { // избегаем бесконечной рекурсии, когда база по какой-то причине не является абсолютной 639 $run++; 640 return fullpath($path, $exists); 641 } 642 } 643 $run = 0; 644 645 // канонизировать 646 $path = explode('/', $path); 647 $newpath = []; 648 foreach ($path as $p) { 649 if ($p === '' || $p === '.') continue; 650 if ($p === '..') { 651 array_pop($newpath); 652 continue; 653 } 654 $newpath[] = $p; 655 } 656 $finalpath = $root . implode('/', $newpath); 657 658 // проверка существования при необходимости (кроме случаев модульного тестирования) 659 if ($exists && !defined('DOKU_UNITTEST') && !file_exists($finalpath)) { 660 return false; 661 } 662 return $finalpath; 663 } 664
«Подробности»
1<?php 2 3/** 4* Инициализируйте некоторые значения по умолчанию, необходимые для DokuWiki 5*/ 6 7использовать dokuwiki \ Extension \ PluginController ; 8использовать dokuwiki \ ErrorHandler ; 9использовать dokuwiki \ Ввод \ Ввод ; 10использовать dokuwiki \ Extension \ Event ; 11использовать dokuwiki \ Extension \ EventHandler ; 12 13/** 14* время выполнения Dokuwiki 15* 16* @param целое число $ начало 17* 18* @return смешанный 19*/ 20функция delta_time ($ start = 0 ) 21{ 22 вернуть микровремя ( true ) - (( float )$ start ); 23} 24определить ( 'DOKU_START_TIME' , delta_time ()); 25 26глобальный $ config_cascade ; 27$ config_cascade = []; 28 29// если доступно, загрузите файл конфигурации предварительной загрузки 30$ preload = полный_путь ( __DIR__ ). '/ preload.php ' ; 31если ( file_exists ($ preload )) включить ($ preload ); 32 33// определить путь включения 34если (! определено ( 'DOKU_INC' )) определить ( 'DOKU_INC' , полный путь ( __DIR__ . '/../' ) . '/' ); 35 36// определить каталог плагина 37если (! определено ( 'DOKU_PLUGIN' )) определить ( 'DOKU_PLUGIN' , DOKU_INC . ' lib / plugins /' ); 38 39// определить путь конфигурации (упаковщики могут захотеть изменить его на / etc / dokuwiki /) 40если (! определено ( 'DOKU_CONF' )) определить ( 'DOKU_CONF' , DOKU_INC . 'conf/' ); 41 42// проверьте переопределение сообщений об ошибках или установите для сообщений об ошибках разумные значения 43если (! определено ( 'DOKU_E_LEVEL' ) && file_exists ( DOKU_CONF . 'report_e_all' )) { 44 определить ( 'DOKU_E_LEVEL' , E_ALL ); 45} 46если (! определено ( 'DOKU_E_LEVEL' )) { 47 error_reporting ( E_ALL & ~ E_NOTICE & ~ E_DEPRECATED ); 48} еще { 49 error_reporting ( DOKU_E_LEVEL ); 50} 51 52// избегайте проблем с кэшированием #1594 53заголовок ( 'Vary: Cookie' ); 54 55// инициализация кэшей памяти 56глобальный $ cache_revinfo ; 57 $ cache_revinfo = []; 58глобальный $ cache_wikifn ; 59 $ cache_wikifn = []; 60глобальный $ cache_cleanid ; 61 $ cache_cleanid = []; 62глобальный $ cache_authname ; 63 $ cache_authname = []; 64глобальные $ cache_metadata ; 65 $ cache_metadata = []; 66 67// всегда включайте ' inc / config_cascade.php ' 68// ранее заданные в preload.php поля $config_cascade будут объединены со значениями по умолчанию 69включить ( DOKU_INC . ' inc / config_cascade.php ' ); 70 71//подготовить массив конфигурации() 72глобальная $ conf ; 73$ conf = []; 74 75// загрузить глобальный файл(ы) конфигурации 76foreach ([ 'default' , 'local' , 'protected' ] как $ config_group ) { 77 если ( пусто ($ config_cascade [ 'main' ][$ config_group ])) продолжить ; 78 foreach ($ config_cascade [ 'main' ][$ config_group ] как $ config_file ) { 79 если ( file_exists ($ config_file )) { 80 включить ($ config_file ); 81 } 82 } 83} 84 85//подготовить массив лицензий() 86глобальная лицензия $ ; 87$ лицензия = []; 88 89// загрузить файл(ы) лицензии 90foreach ([ 'default' , 'local' ] как $ config_group ) { 91 если ( пусто ($ config_cascade [ 'license' ][$ config_group ])) продолжить ; 92 foreach ($ config_cascade [ 'license' ][$ config_group ] как $ config_file ) { 93 если ( file_exists ($ config_file )) { 94 включить ($ config_file ); 95 } 96 } 97} 98 99// установить часовой пояс (как в днях до 5.3.0) 100date_default_timezone_set (@date_default_timezone_get ( )); 101 102// определить baseURL 103if (! определено ( 'DOKU_REL' )) define ( 'DOKU_REL' , getBaseURL ( false )); 104если (! определено ( 'DOKU_URL' )) определить ( 'DOKU_URL' , getBaseURL ( true )); 105если (! определено ( 'DOKU_BASE' )) { 106 если ($ conf [ 'канонический' ]) { 107 определить ( 'DOKU_BASE' , DOKU_URL ); 108 } еще { 109 определить ( 'DOKU_BASE' , DOKU_REL ); 110 } 111} 112 113// определяем пробелы 114если (! определено ( 'NL' )) определить ( 'NL' , " \n " ); 115если (! определено ( 'DOKU_LF' )) определить ( 'DOKU_LF' , " \n " ); 116если (! определено ( 'DOKU_TAB' )) определить ( 'DOKU_TAB' , " \t " ); 117 118// определить cookie и идентификатор сеанса, добавить порт сервера, если настроен securecookie FS#1664 119если (! определено ( 'DOKU_COOKIE' )) { 120 $ serverPort = $ _SERVER [ 'SERVER_PORT' ] ?? '' ; 121 define ( 'DOKU_COOKIE' , 'DW' . md5 ( DOKU_REL . (($ conf [ 'securecookie' ])? $ serverPort : '' ))); 122 не установлен ($ serverPort ); 123} 124 125// определить основной скрипт 126если (! определено ( 'DOKU_SCRIPT' )) определить ( 'DOKU_SCRIPT' , ' doku.php ' ); 127 128если (! определено ( 'DOKU_TPL' )) { 129 /** 130 * @deprecated 2012-10-13 заменен более динамичным методом 131 * @see tpl_basedir () 132 */ 133 определить ( 'DOKU_TPL' , DOKU_BASE . ' lib / tpl /' . $ conf [ 'template' ] . '/' ); 134} 135 136если (! определено ( 'DOKU_TPLINC' )) { 137 /** 138 * @deprecated 2012-10-13 заменен более динамичным методом 139 * @see tpl_incdir () 140 */ 141 определить ( 'DOKU_TPLINC' , DOKU_INC . ' lib / tpl /' . $ conf [ 'template' ] . '/' ); 142} 143 144// сделать перезапись сеанса XHTML-совместимой 145@ ini_set ( 'arg_separator.output' , '&' ); 146 147// убедитесь, что глобальная zlib не мешает FS#1132 148@ ini_set ( 'zlib.output_compression' , 'off' ); 149 150// увеличить предел возврата PCRE 151@ ini_set ( 'pcre.backtrack_limit' , '20971520' ); 152 153// включить сжатие gzip, если поддерживается 154$ httpAcceptEncoding = $ _SERVER [ 'HTTP_ACCEPT_ENCODING' ] ?? '' ; 155$ conf [ 'gzip_output' ] &= ( strpos ( $ httpAcceptEncoding , 'gzip' ) !== false ); 156глобальный $ ACT ; 157если ( 158 $ conf [ 'gzip_output' ] && 159 ! определено ( 'DOKU_DISABLE_GZIP_OUTPUT' ) && 160 function_exists ( 'ob_gzhandler' ) && 161 // Отключить сжатие, если может быть доставлена (сжатая) карта сайта 162 // См. https://bugs.dokuwiki.org/index.php?do=details&task_id=2576 163 $ ACT != 'карта сайта' 164) { 165 ob_start ( 'ob_gzhandler' ); 166} 167 168// инициализация сеанса 169если (! headers_sent () && ! defined ( 'NOSESSION' )) { 170 if (! определено ( 'DOKU_SESSION_NAME' )) define ( 'DOKU_SESSION_NAME' , "DokuWiki" ); 171 если (! определено ( 'DOKU_SESSION_LIFETIME' )) определить ( 'DOKU_SESSION_LIFETIME' , 0 ); 172 если (! определено ( 'DOKU_SESSION_PATH' )) { 173 $ cookieDir = пусто ($ conf [ 'cookiedir' ]) ? DOKU_REL : $ conf [ 'cookiedir' ]; 174 определить ( 'DOKU_SESSION_PATH' , $ cookieDir ); 175 } 176 если (! определено ( 'DOKU_SESSION_DOMAIN' )) определить ( 'DOKU_SESSION_DOMAIN' , '' ); 177 178 // начать сеанс 179 init_session (); 180 181 // загрузить оставшиеся сообщения 182 если ( isset ($ _SESSION [ DOKU_COOKIE ][ 'сообщение' ])) { 183 $ MSG = $ _SESSION [ DOKU_COOKIE ][ 'сообщение' ]; 184 сброшено ($ _SESSION [ DOKU_COOKIE ][ 'сообщение' ]); 185 } 186} 187 188// не позволяйте куки-файлам вмешиваться в переменные запроса 189$ _REQUEST = array_merge ($ _GET , $ _POST ); 190 191// мы не хотим, чтобы URL-адрес очистки был выкопан 192если ( isset ($ _REQUEST [ 'purge' ]) && ! empty ($ _SERVER [ 'HTTP_REFERER' ])) unset ($ _REQUEST [ 'purge' ]); 193 194// предварительно рассчитать режимы создания файла 195init_creationmodes (); 196 197// создаем реальные пути и проверяем их 198init_paths (); 199init_files (); 200 201// настройка класса контроллера плагина (можно перезаписать в preload.php ) 202глобальный $ plugin_controller_class , $ plugin_controller ; 203если ( пусто ($ plugin_controller_class )) $ plugin_controller_class = PluginController :: class ; 204 205// автозагрузчик 206require_once ( DOKU_INC . ' inc / load.php ' ); 207 208// отныне все является исключением 209ErrorHandler :: register (); 210 211// отключаем gzip, если недоступно 212определить ( 'DOKU_HAS_BZIP' , function_exists ( 'bzopen' )); 213определить ( 'DOKU_HAS_GZIP' , function_exists ( 'gzopen' )); 214если ($ conf [ 'сжатие' ] == 'bz2' && ! DOKU_HAS_BZIP ) { 215 $ conf [ 'сжатие' ] = 'gz' ; 216} 217если ($ conf [ 'сжатие' ] == 'gz' && ! DOKU_HAS_GZIP ) { 218 $ conf [ 'сжатие' ] = 0 ; 219} 220 221// класс обработки входных данных 222глобальный $ ВХОД ; 223$ INPUT = новый Вход (); 224 225// инициализируем контроллер плагина 226$ plugin_controller = новый $ plugin_controller_class (); 227 228// инициализируем обработчик событий 229глобальный $ EVENT_HANDLER ; 230$ EVENT_HANDLER = новый EventHandler (); 231 232$ local = $ conf [ 'язык' ]; 233Событие :: createAndTrigger ( 'INIT_LANG_LOAD' , $ local , 'init_lang' , true ); 234 235 236// настройка системы аутентификации 237если (! определено ( 'NOSESSION' )) { 238 auth_setup (); 239} 240 241// настройка почтовой системы 242mail_setup (); 243 244$ nil = ноль ; 245Событие :: createAndTrigger ( 'DOKUWIKI_INIT_DONE' , $ nil , null , false ); 246 247/** 248* Инициализирует сеанс 249* 250* Проверяет, что переданный сеансовый cookie-файл действителен, недействительные игнорируются, и выдается новый идентификатор сеанса 251* 252* @ссылка http://stackoverflow.com/a/33024310/172068 253* @ссылка http://php.net/manual/en/session.configuration.php#ini.session.sid-length 254*/ 255функция init_session () 256{ 257 глобальная $ conf ; 258 имя_сеанса ( DOKU_SESSION_NAME ); 259 session_set_cookie_params ([ 260 'время жизни' => DOKU_SESSION_LIFETIME , 261 'путь' => DOKU_SESSION_PATH , 262 'домен' => DOKU_SESSION_DOMAIN , 263 'secure' => ($ conf [ 'securecookie' ] && is_ssl ()), 264 'httponly' => правда , 265 'samesite' => 'Лакс' , 266 ]); 267 268 // убедитесь, что cookie-файл сеанса содержит действительный идентификатор сеанса 269 если ( isset ($ _COOKIE [ ИМЯ_СЕАНСА_ДОКУ ]) && ! preg_match ( '/^[-,a-zA-Z0-9]{22,256}$/' , $ _COOKIE [ ИМЯ_СЕАНСА_ДОКУ ])) { 270 не установлено ($ _COOKIE [ DOKU_SESSION_NAME ]); 271 } 272 273 session_start (); 274} 275 276 277/** 278* Проверяет пути из файла конфигурации 279*/ 280функция init_paths () 281{ 282 глобальная $ conf ; 283 284 $ пути = [ 285 'datadir' => 'страницы' , 286 'olddir' => 'чердак' , 287 'mediadir' => 'медиа' , 288 'mediaolddir' => 'media_attic' , 289 'metadir' => 'мета' , 290 'mediametadir' => 'media_meta' , 291 'cachedir' => 'кэш' , 292 'indexdir' => 'index' , 293 'lockdir' => 'замки' , 294 'tmpdir' => 'tmp' , 295 'logdir' => 'журнал' , 296 ]; 297 298 foreach ($ пути как $ c => $ p ) { 299 $ path = empty ($ conf [$ c ]) ? $ conf [ 'savedir' ] . '/' . $ p : $ conf [$ c ]; 300 $ conf [$ c ] = init_path ($ path ); 301 если ( пусто ($ conf [$ c ])) { 302 $ path = полный_путь ($ path ); 303 nice_die ( " $ c (' $ p ') по адресу $ path не найден, недоступен или недоступен для записи. 304 Вам следует проверить конфигурацию и настройки разрешений. 305 Или, может быть, вы хотите <a href= \" install.php \" > запустить 306 установщик</a>?" ); 307 } 308 } 309 310 // путь к старому списку изменений нужен только для обновления 311 $ conf [ 'changelog_old' ] = init_path ( 312 $ conf [ 'changelog' ] ?? $ conf [ 'savedir' ] . '/changes.log' 313 ); 314 если ($ conf [ 'changelog_old' ] == '' ) { 315 сброшено ($ conf [ 'changelog_old' ]); 316 } 317 // жестко запрограммирован журнал изменений, поскольку теперь это кэш, который находится в метаданных 318 $ conf [ 'changelog' ] = $ conf [ 'metadir' ] . '/_dokuwiki.changes' ; 319 $ conf [ 'media_changelog' ] = $ conf [ 'metadir' ] . '/_media.changes' ; 320} 321 322/** 323* Загрузить языковые строки 324* 325* @param string $ langCode код языка, переданный обработчиком событий 326*/ 327функция init_lang ($ langCode ) 328{ 329 //подготовить языковой массив 330 глобальный $ lang , $ config_cascade ; 331 $ lang = []; 332 333 //загрузить языковые файлы 334 требуется ( DOKU_INC . ' inc / lang / en / lang.php ' ); 335 foreach ($ config_cascade [ 'lang' ][ 'core' ] как $ config_file ) { 336 если ( file_exists ($ config_file . ' en / lang.php ' )) { 337 include ( $ config_file.'en / lang.php ' ) ; 338 } 339 } 340 341 if ($ langCode && $ langCode != 'en' ) { 342 if ( file_exists ( DOKU_INC . " inc / lang / $ langCode / lang.php " ) { 343 требуется ( DOKU_INC . " inc / lang / $ langCode / lang.php " ); 344 } 345 foreach ($ config_cascade [ 'lang' ][ 'core' ] как $ config_file ) { 346 если ( file_exists ($ config_file . " $ langCode / lang.php " )) { 347 include ($ config_file . " $ langCode / lang.php " ); 348 } 349 } 350 } 351} 352 353/** 354* Проверяет наличие определенных файлов и создает их, если они отсутствуют. 355*/ 356функция init_files () 357{ 358 глобальная $ conf ; 359 360 $ files = [$ conf [ 'indexdir' ] . '/page.idx' ]; 361 362 foreach ($ файлы как $ файл ) { 363 если (! file_exists ($ file )) { 364 $ fh = @ fopen ($ file , 'a' ); 365 если ($ фх ) { 366 fclose ($ fh ); 367 если ($ conf [ 'fperm' ]) chmod ($ file , $ conf [ 'fperm' ]); 368 } еще { 369 nice_die ( " $ file недоступен для записи. Проверьте настройки прав доступа!" ); 370 } 371 } 372 } 373} 374 375/** 376* Возвращает абсолютный путь 377* 378* Сначала проверяется указанный путь, затем DOKU_INC. 379* Проверьте также доступность каталогов. 380* 381* @автор Андреас Гор <andi@splitbrain.org> 382* 383* @param string $ path 384* 385* @return bool | строка 386*/ 387функция init_path ($ path ) 388{ 389 // проверка существования 390 $ p = полный путь ($ path ); 391 если (! file_exists ($ p )) { 392 $ p = полный_путь ( DOKU_INC . $ path ); 393 если (! file_exists ($ p )) { 394 возвращаться '' ; 395 } 396 } 397 398 // проверка возможности записи 399 если (!@ is_writable ($ p )) { 400 возвращаться '' ; 401 } 402 403 // проверка доступности (бит выполнения) для каталогов 404 если (@is_dir ( $ p ) &&! file_exists ( " $ p /." )) { 405 возвращаться '' ; 406 } 407 408 вернуть $ p ; 409} 410 411/** 412* Устанавливает внутренние значения конфигурации fperm и dperm, которые, если установлены, 413* будет использоваться для изменения разрешения вновь созданного каталога или 414* файл с chmod. Учитывает влияние umask системы 415* установка значений только при необходимости. 416*/ 417функция init_creationmodes () 418{ 419 глобальная $ conf ; 420 421 // Устаревшая поддержка старой схемы umask / dmask 422 сброшено ($ conf [ 'dmask' ]); 423 сброшено ($ conf [ 'fmask' ]); 424 не установлено ($ conf [ 'umask' ]); 425 426 $ conf [ 'fperm' ] = false ; 427 $ conf [ 'dperm' ] = false ; 428 429 // получить системную маску umask, вернуться к 0, если она недоступна 430 $ umask = @ umask (); 431 если (!$ umask ) $ umask = 0000 ; 432 433 // проверка того, что автоматически устанавливается системой при создании файла 434 // и устанавливаем параметр fperm, если это не то, что нам нужно 435 $ auto_fmode = 0666 & ~$ umask ; 436 если ($ auto_fmode != $ conf [ 'fmode' ]) $ conf [ 'fperm' ] = $ conf [ 'fmode' ]; 437 438 // проверка того, что автоматически устанавливается системой при создании каталога 439 // и устанавливаем параметр dperm, если это не то, что нам нужно. 440 $ auto_dmode = 0777 & ~$ umask ; 441 если ($ auto_dmode != $ conf [ 'dmode' ]) $ conf [ 'dperm' ] = $ conf [ 'dmode' ]; 442} 443 444/** 445* Возвращает полный абсолютный URL-адрес каталога, где 446* DokuWiki установлен в (включая завершающий слеш) 447* 448* !! Невозможно получить доступ к значениям $_SERVER через $INPUT 449* !! здесь, поскольку эта функция вызывается до $INPUT 450* !! инициализировано. 451* 452* @автор Андреас Гор <andi@splitbrain.org> 453* 454* @param null | bool $ abs Вернуть абсолютный URL? (по умолчанию null — $conf['canonical']) 455* 456* @возвращаемая строка 457*/ 458функция getBaseURL ($ abs = null ) 459{ 460 глобальная $ conf ; 461 462 $ abs ??= $ conf [ 'канонический' ]; 463 464 if (! пусто ($ conf [ 'basedir' ])) { 465 $ dir = $ conf [ 'basedir' ]; 466 } elseif ( substr ($ _SERVER [ 'SCRIPT_NAME' ], -4 ) == '.php' ) { 467 $ dir = dirname ($ _SERVER [ 'SCRIPT_NAME' ]); 468 } elseif ( substr ($ _SERVER [ 'PHP_SELF' ], -4 ) == '.php' ) { 469 $ dir = имя_каталога ($ _SERVER [ 'PHP_SELF' ]); 470 } elseif ($ _SERVER [ 'DOCUMENT_ROOT' ] && $ _SERVER [ 'SCRIPT_FILENAME' ]) { 471 $ dir = preg_replace ( 472 '/^' . preg_quote ($ _SERVER [ 'DOCUMENT_ROOT' ], '/' ) . '/' , 473 '' , 474 $ _SERVER [ 'имя_файла_сценария' ] 475 ); 476 $ dir = имя_каталога ( '/' . $ dir ); 477 } еще { 478 $ dir = '' ; //возможно, это неверно, но мы предполагаем, что он в корне 479 } 480 481 $ dir = str_replace ( ' \\ ' , '/' , $ dir ); // исправление странного поведения WIN 482 $ dir = preg_replace ( '#//+#' , '/' , "/ $ dir /" ); // гарантируем начальные и конечные слеши 483 484 //обработка скрипта в каталоге lib / exe 485 $ dir = preg_replace ( '! lib / exe /$!' , '' , $ dir ); 486 487 //обработка скрипта в каталоге lib / plugins 488 $ dir = preg_replace ( '! lib / plugins /.*$!' , '' , $ dir ); 489 490 //завершить здесь для относительных URL-адресов 491 если (!$ abs ) вернуть $ dir ; 492 493 //используйте конфигурацию, если она доступна, обрежьте все слеши в конце baseurl, чтобы избежать нескольких последовательных слешей в пути 494 если (! пусто ($ conf [ 'baseurl' ])) вернуть rtrim ($ conf [ 'baseurl' ], '/' ) . $ dir ; 495 496 //разделить заголовок хоста на хост и порт 497 если ( isset ($ _SERVER [ 'HTTP_HOST' ])) { 498 если ( 499 (! пусто ($ conf [ 'trustedproxy' ])) && isset ($ _SERVER [ 'HTTP_X_FORWARDED_HOST' ]) 500 && preg_match ( '/' . $ conf [ 'trustedproxy' ]. '/' , $ _SERVER [ 'REMOTE_ADDR' ]) 501 ) { 502 $ cur_host = $ _SERVER [ 'HTTP_X_FORWARDED_HOST' ]; 503 } еще { 504 $ cur_host = $ _SERVER [ 'HTTP_HOST' ]; 505 } 506 $ parsed_host = parse_url ( ' http://' . $cur_host); 507 $host = $parsed_host[' хост '] ?? ' '; 508 $port = $parsed_host[' порт '] ?? ' '; 509 } elseif (isset($_SERVER[' ИМЯ_СЕРВЕРА '])) { 510 $parsed_host = parse_url(' http : //' . $_SERVER['SERVER_NAME']); 511 $ host = $ parsed_host [ 'host' ] ?? '' ; 512 $ port = $ parsed_host [ 'port' ] ?? '' ; 513 } еще { 514 $ host = php_uname ( 'n' ); 515 $ порт = '' ; 516 } 517 518 если (! is_ssl ()) { 519 $ proto = ' http://'; 520 если ($port == ' 80 ') { 521 $порт = ' '; 522 } 523 } еще { 524 $proto = ' https : //'; 525 если ($ порт == '443' ) { 526 $ порт = '' ; 527 } 528 } 529 530 если ($ порт !== '' ) $ порт = ':' . $ порт ; 531 532 return $ proto .$ host .$ port .$ dir ; 533} 534 535/** 536* Проверьте, доступен ли сайт через HTTPS 537* 538* Apache оставляет ,$_SERVER['HTTPS'] пустым, когда он недоступен, IIS устанавливает его в значение «выкл.». 539* «ложь» и «отключено» — это всего лишь предположения 540* 541* @returns bool true, когда SSL активен 542*/ 543функция is_ssl () 544{ 545 глобальная $ conf ; 546 547 // проверяем, находимся ли мы за обратным прокси-сервером 548 если ( 549 (! пусто ($ conf [ 'trustedproxy' ])) && isset ($ _SERVER [ 'HTTP_X_FORWARDED_PROTO' ]) 550 && preg_match ( '/' . $ conf [ 'trustedproxy' ]. '/' , $ _SERVER [ 'REMOTE_ADDR' ]) 551 && ($ _SERVER [ 'HTTP_X_FORWARDED_PROTO' ] == 'https' ) 552 ) { 553 вернуть истину ; 554 } 555 556 если ( preg_match ( '/^(|выкл|ложь|отключено)$/i' , $ _SERVER [ 'HTTPS' ] ?? 'выкл' )) { 557 вернуть ложь ; 558 } 559 560 вернуть истину ; 561} 562 563/** 564* проверяет, что это ОС Windows 565* @return bool 566*/ 567функция isWindows () 568{ 569 return strtoupper ( substr ( PHP_OS , 0 , 3 )) === 'WIN' ; 570} 571 572/** 573* вывести приятное сообщение, даже если ни один стили еще не загружен. 574* 575* @param целое число | строка $ сообщение 576*/ 577функция nice_die ($ msg ) 578{ 579 эхо <<< EOT 580<!DOCTYPE html> 581<html> 582<head><title>Ошибка установки DokuWiki</title></head> 583<body style="font-family: Arial, sans-serif"> 584 <div style="width:60%; margin: auto; background-color: #fcc; 585 рамка: 1px сплошная #faa; отступ: 0.5em 1em;"> 586 <h1 style="font-size: 120%">Ошибка установки DokuWiki</h1> 587 <p> $ сообщение </p> 588 </div> 589</тело> 590</html> 591СРВ ; 592 если ( определено ( 'DOKU_UNITTEST' )) { 593 throw new RuntimeException ( 'nice_die: ' . $ msg ); 594 } 595 выход ( 1 ); 596} 597 598/** 599* Замена realpath() 600* 601* Эта функция ведет себя аналогично функции realpath() в PHP, но не разрешает 602* символические ссылки или доступ к верхним каталогам 603* 604* @автор Андреас Гор <andi@splitbrain.org> 605* @author <richpageau at yahoo dot co dot uk> 606* @ссылка http://php.net/manual/en/function.realpath.php#75992 607* 608* @param string $ path 609* @param bool $ существует 610* 611* @return bool | строка 612*/ 613функция полный_путь ($ путь , $ существует = ложь ) 614{ 615 статический $ run = 0 ; 616 $ корень = '' ; 617 $ iswin = ( isWindows () || ! пусто ($ GLOBALS [ 'DOKU_UNITTEST_ASSUME_WINDOWS' ])); 618 619 // найти (неразрушаемый) корень пути - сохраняет содержимое Windows нетронутым 620 если ($ путь [ 0 ] == '/' ) { 621 $ корень = '/' ; 622 } elseif ($ iswin ) { 623 // сопоставить букву диска и пути UNC 624 если ( preg_match ( '!^([a-zA-z]:)(.*)!' , $ path , $ match )) { 625 $ root = $ match [ 1 ] . '/' ; 626 $ путь = $ совпадение [ 2 ]; 627 } elseif ( preg_match ( '!^( \\ \\ \\ \\ [^ \\ \\ /]+ \\ \\ [^ \\ \\ /]+[ \\ \\ /])(.*)!' , $ path , $ match )) { 628 $ корень = $ матч [ 1 ]; 629 $ путь = $ совпадение [ 2 ]; 630 } 631 } 632 $ path = str_replace ( ' \\ ' , '/' , $ path ); 633 634 // если указанный путь еще не был абсолютным, добавьте путь к скрипту и повторите попытку 635 если (!$ корень ) { 636 $ base = dirname ($ _SERVER [ 'SCRIPT_FILENAME' ]); 637 $ path = $ base . '/' .$ path ; 638 if ($ run == 0 ) { // избегаем бесконечной рекурсии, когда база по какой-то причине не является абсолютной 639 $ запустить ++; 640 вернуть полный путь ($ path , $ existences ); 641 } 642 } 643 $ запуск = 0 ; 644 645 // канонизировать 646 $ path = взорвать ( '/' , $ path ); 647 $ новый_путь = []; 648 foreach ($ path как $ p ) { 649 если ($ p === '' || $ p === '.' ) продолжить ; 650 если ($ p === '..' ) { 651 array_pop ($ newpath ); 652 продолжать ; 653 } 654 $ newpath [] = $ p ; 655 } 656 $ окончательный путь = $ корень . implode ( '/' , $ newpath ); 657 658 // проверка существования при необходимости (кроме случаев модульного тестирования) 659 если ($ существует && ! определено ( 'DOKU_UNITTEST' ) && ! file_exists ($ finalpath )) { 660 вернуть ложь ; 661 } 662 вернуть $ finalpath ; 663} 664
Только авторизованные участники могут оставлять комментарии.
wiki/xref/dokuwiki/inc/init.php.txt · Последнее изменение: 2025/01/03 14:46 — vladpolskiy