Textpattern | PHP Cross Reference | Content Management Systems |
1 <?php 2 3 /* 4 * Textpattern Content Management System 5 * https://textpattern.com/ 6 * 7 * Copyright (C) 2020 The Textpattern Development Team 8 * 9 * This file is part of Textpattern. 10 * 11 * Textpattern is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License 13 * as published by the Free Software Foundation, version 2. 14 * 15 * Textpattern is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with Textpattern. If not, see <https://www.gnu.org/licenses/>. 22 */ 23 24 if (!defined('txpath')) { 25 define("txpath", dirname(dirname(__FILE__))); 26 } 27 28 define("txpinterface", "admin"); 29 error_reporting(E_ALL | E_STRICT); 30 @ini_set("display_errors", "1"); 31 32 define('MSG_OK', 'alert-block success'); 33 define('MSG_ALERT', 'alert-block warning'); 34 define('MSG_ERROR', 'alert-block error'); 35 36 include_once txpath.'/lib/class.trace.php'; 37 $trace = new Trace(); 38 include_once txpath.'/lib/constants.php'; 39 include_once txpath.'/lib/txplib_misc.php'; 40 include_once txpath.'/lib/txplib_admin.php'; 41 include_once txpath.'/vendors/Textpattern/Loader.php'; 42 43 $loader = new \Textpattern\Loader(txpath.DS.'vendors'); 44 $loader->register(); 45 46 $loader = new \Textpattern\Loader(txpath.DS.'lib'); 47 $loader->register(); 48 49 if (!isset($_SESSION)) { 50 if (headers_sent()) { 51 $_SESSION = array(); 52 } else { 53 session_start(); 54 } 55 } 56 57 include_once txpath.'/lib/txplib_html.php'; 58 include_once txpath.'/lib/txplib_forms.php'; 59 include_once txpath.'/include/txp_auth.php'; 60 include_once txpath.'/setup/setup_lib.php'; 61 62 assert_system_requirements(); 63 64 header("Content-Type: text/html; charset=utf-8"); 65 66 // Drop trailing cruft. 67 $_SERVER['PHP_SELF'] = preg_replace('#^(.*index.php).*$#i', '$1', $_SERVER['PHP_SELF']); 68 69 // Sniff out the 'textpattern' directory's name '/path/to/site/textpattern/setup/index.php'. 70 $txpdir = explode('/', $_SERVER['PHP_SELF']); 71 72 if (count($txpdir) > 3) { 73 // We live in the regular directory structure. 74 $txpdir = DS.$txpdir[count($txpdir) - 3]; 75 } else { 76 // We probably came here from a clever assortment of symlinks and DocumentRoot. 77 $txpdir = DS; 78 } 79 80 $prefs = array(); 81 $prefs['module_pophelp'] = 1; 82 $step = ps('step'); 83 84 // Be kind to Windows: replace directory separator with '/' since 85 // PHP returns $_SERVER variables in that form. 86 $pattern = "#^(.*?)(".str_replace(DS, '/', $txpdir).")?/setup.*$#i"; 87 $rel_siteurl = preg_replace($pattern, '$1', $_SERVER['PHP_SELF']); 88 $rel_txpurl = rtrim(dirname(dirname($_SERVER['PHP_SELF'])), DS); 89 90 if (empty($_SESSION['cfg'])) { 91 $cfg = json_decode(txp_get_contents(dirname(__FILE__).DS.'.default.json'), true); 92 } else { 93 $cfg = $_SESSION['cfg']; 94 } 95 96 if (ps('lang')) { 97 $cfg['site']['language_code'] = ps('lang'); 98 } 99 if (empty($cfg['site']['language_code'])) { 100 $cfg['site']['language_code'] = TEXTPATTERN_DEFAULT_LANG; 101 } 102 setup_load_lang($cfg['site']['language_code']); 103 104 if (defined('is_multisite')) { 105 $config_path = multisite_root_path.DS.'private'; 106 } else { 107 $config_path = txpath; 108 } 109 110 111 $protocol = (empty($_SERVER['HTTPS']) || @$_SERVER['HTTPS'] == 'off') ? 'http://' : 'https://'; 112 if (defined('is_multisite')) { 113 if (empty($cfg['site']['admin_url'])) { 114 $cfg['site']['admin_url'] = $protocol. 115 (@$_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']; 116 } 117 if (empty($cfg['site']['cookie_domain'])) { 118 $cfg['site']['cookie_domain'] = substr($cfg['site']['admin_url'], strpos($cfg['site']['admin_url'], '.') + 1); 119 } 120 if (empty($cfg['site']['public_url'])) { 121 $cfg['site']['public_url'] = $protocol.'www.'.$cfg['site']['cookie_domain']; 122 } 123 } 124 if (empty($cfg['site']['public_url'])) { 125 if (@$_SERVER['SCRIPT_NAME'] && (@$_SERVER['SERVER_NAME'] || @$_SERVER['HTTP_HOST'])) { 126 $cfg['site']['public_url'] = $protocol. 127 ((@$_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']).$rel_siteurl; 128 } else { 129 $cfg['site']['public_url'] = $protocol.'mysite.com'; 130 } 131 } 132 133 134 switch ($step) { 135 case '': 136 step_chooseLang(); 137 break; 138 case 'step_getDbInfo': 139 step_getDbInfo(); 140 break; 141 case 'step_getTxpLogin': 142 step_getTxpLogin(); 143 break; 144 case 'step_printConfig': 145 step_printConfig(); 146 break; 147 case 'step_createTxp': 148 step_createTxp(); 149 } 150 $_SESSION['cfg'] = $cfg; 151 exit("</main>\n</body>\n</html>"); 152 153 154 /** 155 * Return the top of page furniture. 156 * 157 * @return HTML 158 */ 159 160 function preamble() 161 { 162 global $textarray_script, $cfg, $step; 163 164 $out = array(); 165 $bodyclass = ($step == '') ? ' welcome' : ''; 166 gTxtScript(array('help')); 167 168 if (isset($cfg['site']['language_code']) && !isset($_SESSION['direction'])) { 169 $file = Txp::get('\Textpattern\L10n\Lang', txpath.DS.'setup'.DS.'lang'.DS)->findFilename($cfg['site']['language_code']); 170 $meta = Txp::get('\Textpattern\L10n\Lang', txpath.DS.'setup'.DS.'lang'.DS)->fetchMeta($file); 171 $_SESSION['direction'] = isset($meta['direction']) ? $meta['direction'] : 'ltr'; 172 } 173 174 $textDirection = (isset($_SESSION['direction'])) ? ' dir="'.$_SESSION['direction'].'"' : 'ltr'; 175 176 $out[] = <<<eod 177 <!DOCTYPE html> 178 <html lang="en"{$textDirection}> 179 <head> 180 <meta charset="utf-8"> 181 <meta name="robots" content="noindex, nofollow"> 182 <title>Setup | Textpattern CMS</title> 183 eod; 184 185 $out[] = script_js('../vendors/jquery/jquery/jquery.js', TEXTPATTERN_SCRIPT_URL). 186 script_js('../vendors/jquery/jquery-ui/jquery-ui.js', TEXTPATTERN_SCRIPT_URL). 187 script_js( 188 'var textpattern = '.json_encode(array( 189 'prefs' => (object) null, 190 'event' => 'setup', 191 'step' => $step, 192 'textarray' => (object) $textarray_script, 193 ), TEXTPATTERN_JSON).';'). 194 script_js('../textpattern.js', TEXTPATTERN_SCRIPT_URL); 195 196 $out[] = <<<eod 197 <link rel="stylesheet" href="../admin-themes/hive/assets/css/textpattern.css"> 198 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"> 199 </head> 200 <body class="setup{$bodyclass}" id="page-setup"> 201 <script src="../admin-themes/hive/assets/js/darkmode.js"></script> 202 <main class="txp-body"> 203 eod; 204 205 return join(n, $out); 206 } 207 208 /** 209 * Renders stage 0: welcome/choose language panel. 210 */ 211 212 function step_chooseLang() 213 { 214 $_SESSION['direction'] = 'ltr'; 215 echo preamble(); 216 unset($_SESSION['direction']); 217 echo n.'<div class="txp-setup">', 218 hed('Welcome to Textpattern CMS', 1), 219 n.'<form class="prefs-form" method="post" action="'.txpspecialchars($_SERVER['PHP_SELF']).'">', 220 langs(), 221 graf(fInput('submit', 'Submit', 'Submit', 'publish')), 222 sInput('step_getDbInfo'), 223 n.'</form>', 224 n.'</div>'; 225 } 226 227 /** 228 * Renders progress meter displayed on stages 1 to 4 of installation process. 229 * 230 * @param int $stage The stage 231 */ 232 233 function txp_setup_progress_meter($stage = 1) 234 { 235 $stages = array( 236 1 => gTxt('set_db_details'), 237 2 => gTxt('add_config_file'), 238 3 => gTxt('populate_db'), 239 4 => gTxt('get_started'), 240 ); 241 242 $out = array(); 243 244 $out[] = n.'<aside class="progress-meter">'. 245 graf(gTxt('progress_steps'), ' class="txp-accessibility"'). 246 n.'<ol>'; 247 248 foreach ($stages as $idx => $phase) { 249 $active = ($idx == $stage); 250 $sel = $active ? ' class="active" aria-current="step"' : ''; 251 $out[] = n.'<li'.$sel.'>'.($active ? strong($phase) : $phase).'</li>'; 252 } 253 254 $out[] = n.'</ol>'. 255 n.'</aside>'; 256 257 return join('', $out); 258 } 259 260 /** 261 * Renders stage 1: database details panel. 262 */ 263 264 function step_getDbInfo() 265 { 266 global $cfg; 267 268 echo preamble(); 269 echo txp_setup_progress_meter(1), 270 n.'<div class="txp-setup">'; 271 272 check_config_exists(); 273 274 echo '<form class="prefs-form" method="post" action="'.txpspecialchars($_SERVER['PHP_SELF']).'">'. 275 hed(gTxt('need_details'), 1). 276 hed(tag('MySQL', 'bdi', array('dir' => 'ltr')), 2). 277 graf(gTxt('db_must_exist')). 278 inputLabel( 279 'setup_mysql_login', 280 fInput('text', 'duser', @$cfg['database']['user'], '', '', '', INPUT_REGULAR, '', 'setup_mysql_login'), 281 'mysql_login', '', array('class' => 'txp-form-field') 282 ). 283 inputLabel( 284 'setup_mysql_pass', 285 fInput('password', 'dpass', @$cfg['database']['password'], 'txp-maskable', '', '', INPUT_REGULAR, '', 'setup_mysql_pass'). 286 n.tag( 287 checkbox('unmask', 1, false, 0, 'show_password'). 288 n.tag(gTxt('setup_show_password'), 'label', array('for' => 'show_password')), 289 'div', array('class' => 'show-password')), 290 'mysql_password', '', array('class' => 'txp-form-field') 291 ). 292 inputLabel( 293 'setup_mysql_server', 294 fInput('text', 'dhost', (empty($cfg['database']['host']) ? 'localhost' : $cfg['database']['host']), '', '', '', INPUT_REGULAR, '', 'setup_mysql_server'), 295 'mysql_server', '', array('class' => 'txp-form-field') 296 ). 297 inputLabel( 298 'setup_mysql_db', 299 fInput('text', 'ddb', @$cfg['database']['db_name'], '', '', '', INPUT_REGULAR, '', 'setup_mysql_db', '', true), 300 'mysql_database', '', array('class' => 'txp-form-field') 301 ). 302 inputLabel( 303 'setup_table_prefix', 304 fInput('text', 'dprefix', @$cfg['database']['table_prefix'], 'input-medium', '', '', INPUT_MEDIUM, '', 'setup_table_prefix'), 305 'table_prefix', 'table_prefix', array('class' => 'txp-form-field') 306 ); 307 308 if (defined('is_multisite')) { 309 echo hed( 310 gTxt('multisite_config'), 2 311 ). 312 graf(gTxt('multisite_please_enter_details')). 313 inputLabel( 314 'setup_admin_url', 315 fInput('text', 'adminurl', @$cfg['site']['admin_url'], '', '', '', INPUT_REGULAR, '', 'setup_admin_url', '', true), 316 'multisite_admin_domain', 'setup_admin_url', array('class' => 'txp-form-field') 317 ). 318 inputLabel( 319 'setup_cookie_domain', 320 fInput('text', 'cookiedomain', @$cfg['site']['cookie_domain'], '', '', '', INPUT_REGULAR, '', 'setup_cookie_domain', '', true), 321 'multisite_cookie_domain', 'setup_cookie_domain', array('class' => 'txp-form-field') 322 ); 323 } 324 325 if (is_disabled('mail')) { 326 echo msg(gTxt('warn_mail_unavailable'), MSG_ALERT); 327 } 328 329 echo graf( 330 fInput('submit', 'Submit', gTxt('next_step', '', 'raw'), 'publish') 331 ); 332 333 echo sInput('step_printConfig'). 334 n.'</form>'. 335 n.'</div>'; 336 } 337 338 /** 339 * Renders stage 2: either config details panel (on success) or database details 340 * error message (on fail). 341 */ 342 343 function step_printConfig() 344 { 345 global $cfg; 346 347 $cfg['database']['user'] = ps('duser'); 348 $cfg['database']['password'] = ps('dpass'); 349 $cfg['database']['host'] = ps('dhost'); 350 $cfg['database']['db_name'] = ps('ddb'); 351 $cfg['database']['table_prefix'] = ps('dprefix'); 352 353 if (defined('is_multisite')) { 354 $cfg['site']['admin_url'] = ps('adminurl'); 355 $cfg['site']['cookie_domain'] = ps('cookiedomain'); 356 } 357 358 echo preamble(); 359 echo txp_setup_progress_meter(2). 360 n.'<div class="txp-setup">'; 361 362 check_config_exists(); 363 364 echo hed(gTxt('checking_database'), 2); 365 setup_connect(); 366 367 echo setup_config_contents(). 368 n.'</div>'; 369 } 370 371 /** 372 * Renders either stage 3: admin user details panel (on success), or stage 2: 373 * config details error message (on fail). 374 */ 375 376 function step_getTxpLogin() 377 { 378 global $cfg; 379 380 $problems = array(); 381 382 echo preamble(); 383 check_config_txp(2); 384 385 // Default admin-theme selector. 386 $core_themes = array('classic', 'hive', 'hiveneutral'); 387 388 $vals = \Textpattern\Admin\Theme::names(1); 389 390 foreach ($vals as $key => $title) { 391 $vals[$key] = (in_array($key, $core_themes) ? gTxt('core_theme', array('{theme}' => $title)) : $title); 392 } 393 394 asort($vals, SORT_STRING); 395 396 $theme_chooser = selectInput('theme', $vals, 397 (empty($cfg['site']['admin_theme']) ? 'hive' : $cfg['site']['admin_theme']), 398 '', '', 'setup_admin_theme'); 399 400 $public_themes_class = Txp::get('Textpattern\Skin\Skin'); 401 402 $public_themes_class->setDirPath(txpath.DS.'..'.DS.'themes'); 403 $vals = $public_themes_class->getUploaded(false); 404 405 $public_themes_class->setDirPath(txpath.DS.'setup'.DS.'themes'); 406 $vals = array_merge($public_themes_class->getUploaded(false), $vals); 407 408 $public_theme_name = (empty($cfg['site']['public_theme']) ? 'four-point-eight' : $cfg['site']['public_theme']); 409 410 $public_theme_chooser = selectInput('public_theme', $vals, $public_theme_name, '', '', 'setup_public_theme'); 411 412 echo txp_setup_progress_meter(3). 413 n.'<div class="txp-setup">'. 414 n.'<form class="prefs-form" method="post" action="'.txpspecialchars($_SERVER['PHP_SELF']).'">'. 415 hed( 416 gTxt('creating_db_tables'), 2 417 ). 418 graf( 419 gTxt('about_to_create') 420 ). 421 inputLabel( 422 'setup_user_realname', 423 fInput('text', 'RealName', @$cfg['user']['full_name'], '', '', '', INPUT_REGULAR, '', 'setup_user_realname', '', true), 424 'your_full_name', '', array('class' => 'txp-form-field') 425 ). 426 inputLabel( 427 'setup_user_email', 428 fInput('email', 'email', @$cfg['user']['email'], '', '', '', INPUT_REGULAR, '', 'setup_user_email', '', true), 429 'your_email', '', array('class' => 'txp-form-field') 430 ). 431 inputLabel( 432 'setup_user_login', 433 fInput('text', 'name', @$cfg['user']['login_name'], '', '', '', INPUT_REGULAR, '', 'setup_user_login', '', true), 434 'setup_login', 'setup_user_login', array('class' => 'txp-form-field') 435 ). 436 inputLabel( 437 'setup_user_pass', 438 fInput('password', 'pass', @$cfg['user']['password'], 'txp-maskable', '', '', INPUT_REGULAR, '', 'setup_user_pass', '', true). 439 n.tag( 440 checkbox('unmask', 1, false, 0, 'show_password'). 441 n.tag(gTxt('setup_show_password'), 'label', array('for' => 'show_password')), 442 'div', array('class' => 'show-password')), 443 'choose_password', 'setup_user_pass', array('class' => 'txp-form-field') 444 ). 445 hed( 446 gTxt('site_config'), 2 447 ). 448 inputLabel( 449 'setup_site_url', 450 fInput('text', 'siteurl', @$cfg['site']['public_url'], '', '', '', INPUT_REGULAR, '', 'setup_site_url', '', true), 451 'please_enter_url', 'siteurl', array('class' => 'txp-form-field') 452 ). 453 inputLabel( 454 'setup_admin_theme', 455 $theme_chooser, 456 'admin_theme', 'theme_name', array('class' => 'txp-form-field') 457 ). 458 inputLabel( 459 'setup_public_theme', 460 $public_theme_chooser, 461 'public_theme', 'public_theme_name', array('class' => 'txp-form-field') 462 ). 463 graf( 464 fInput('submit', 'Submit', gTxt('next_step'), 'publish') 465 ). 466 sInput('step_createTxp'). 467 n.'</form>'. 468 n.'</div>'; 469 } 470 471 /** 472 * Re-renders stage 3: admin user details panel, due to user input errors. 473 */ 474 475 function step_createTxp() 476 { 477 global $cfg; 478 479 $cfg['user']['full_name'] = ps('RealName'); 480 $cfg['user']['email'] = ps('email'); 481 $cfg['user']['login_name'] = ps('name'); 482 $cfg['user']['password'] = ps('pass'); 483 484 $cfg['site']['public_url'] = ps('siteurl'); 485 $cfg['site']['admin_theme'] = ps('theme'); 486 $cfg['site']['public_theme'] = ps('public_theme'); 487 $cfg['site']['content_directory'] = ''; 488 489 echo preamble(); 490 491 if (empty($cfg['user']['login_name'])) { 492 echo txp_setup_progress_meter(3).n.'<div class="txp-setup">'; 493 msg(gTxt('name_required'), MSG_ERROR, true); 494 } 495 496 if (empty($cfg['user']['password'])) { 497 echo txp_setup_progress_meter(3).n.'<div class="txp-setup">'; 498 msg(gTxt('pass_required'), MSG_ERROR, true); 499 } 500 501 if (!is_valid_email($cfg['user']['email'])) { 502 echo txp_setup_progress_meter(3).n.'<div class="txp-setup">'; 503 msg(gTxt('email_required'), MSG_ERROR, true); 504 } 505 506 check_config_txp(3); 507 setup_db($cfg); 508 step_fbCreate(); 509 } 510 511 /** 512 * Renders stage 4: either installation completed panel (success) or 513 * installation error message (fail). 514 */ 515 516 function step_fbCreate() 517 { 518 global $cfg; 519 520 unset($cfg['database']['client_flags']); 521 unset($cfg['database']['charset']); 522 $setup_autoinstall_body = gTxt('setup_autoinstall_body')."<pre>". 523 json_encode($cfg, TEXTPATTERN_JSON | JSON_PRETTY_PRINT). 524 "</pre>"; 525 if (defined('is_multisite')) { 526 $multisite_admin_login_url = $GLOBALS['protocol'].$cfg['site']['admin_url']; 527 } 528 529 $warnings = @find_temp_dir() ? '' : msg(gTxt('set_temp_dir_prefs'), MSG_ALERT); 530 if (defined('is_multisite')) { 531 $login_url = $multisite_admin_login_url.DS.'index.php?lang='.$cfg['site']['language_code']; 532 $setup_path = multisite_root_path.DS.'admin'.DS; 533 } else { 534 $login_url = $GLOBALS['rel_txpurl'].DS.'index.php?lang='.$cfg['site']['language_code']; 535 $setup_path = DS.basename(txpath).DS; 536 } 537 538 // Clear the session so no data is leaked. 539 $_SESSION = $cfg = array(); 540 541 echo txp_setup_progress_meter(4). 542 n.'<div class="txp-setup">'. 543 hed(gTxt('that_went_well'), 1). 544 $warnings. 545 graf( 546 gTxt('you_can_access', array('index.php' => $login_url)) 547 ). 548 // graf( 549 // gTxt('setup_autoinstall_text').popHelp('#', 0, 0, 'pophelp', $setup_autoinstall_body) 550 // ). 551 graf( 552 gTxt('installation_postamble', array( 553 '{setuppath}' => $setup_path, 554 )) 555 ). 556 hed(gTxt('thanks_for_interest'), 3). 557 graf( 558 href(gTxt('go_to_login'), $login_url, ' class="navlink publish"') 559 ). 560 n.'</div>'; 561 } 562 563 564 /** 565 * Populate a textarea with config.php file code. 566 * 567 * @return HTML 568 */ 569 570 function setup_config_contents() 571 { 572 global $cfg, $config_path; 573 574 return hed(gTxt('creating_config'), 2). 575 graf( 576 strong(gTxt('before_you_proceed')).' '. 577 gTxt('create_config', array('{configpath}' => $config_path.DS)) 578 ). 579 graf('<a class="txp-button txp-config-download">'.gTxt('download').'</a>'). 580 n.'<textarea class="code" name="config" cols="'.INPUT_LARGE.'" rows="'.TEXTAREA_HEIGHT_REGULAR.'" dir="ltr" readonly>'. 581 setup_makeConfig($cfg, true). 582 n.'</textarea>'. 583 n.'<form method="post" action="'.txpspecialchars($_SERVER['PHP_SELF']).'">'. 584 graf(fInput('submit', 'submit', gTxt('did_it'), 'publish')). 585 sInput('step_getTxpLogin'). 586 n.'</form>'; 587 } 588 589 590 /** 591 * Render a 'back' button that goes to the correct step. 592 * 593 * @return HTML 594 */ 595 596 function setup_back_button() 597 { 598 global $step; 599 600 $prevSteps = array( 601 'step_getDbInfo' => '', 602 'step_getTxpLogin' => 'step_getDbInfo', 603 'step_printConfig' => 'step_getDbInfo', 604 'step_createTxp' => 'step_getTxpLogin', 605 'step_fbCreate' => 'step_createTxp', 606 ); 607 608 $prev = isset($prevSteps[$step]) ? $prevSteps[$step] : ''; 609 610 return graf(gTxt('please_go_back')). 611 n.'<form method="post" action="'.txpspecialchars($_SERVER['PHP_SELF']).'">'. 612 sInput($prev). 613 fInput('submit', 'submit', gTxt('back'), 'navlink publish'). 614 n.'</form>'; 615 } 616 617 /** 618 * Fetch a dropdown of available languages. 619 * 620 * The list is fetched from the file system of translations. 621 * 622 * @return array 623 */ 624 625 function langs() 626 { 627 global $cfg; 628 629 $files = Txp::get('\Textpattern\L10n\Lang', txpath.DS.'setup'.DS.'lang'.DS)->files(); 630 $langs = array(); 631 632 $out = n.'<div class="txp-form-field">'. 633 n.'<div class="txp-form-field-label">'. 634 n.'<label for="setup_language">Please choose a language</label>'. 635 n.'</div>'. 636 n.'<div class="txp-form-field-value">'. 637 n.'<select id="setup_language" name="lang" autocomplete="language">'; 638 639 if (is_array($files) && !empty($files)) { 640 foreach ($files as $file) { 641 $meta = Txp::get('\Textpattern\L10n\Lang', txpath.DS.'setup'.DS.'lang'.DS)->fetchMeta($file); 642 643 if (! empty($meta['code'])) { 644 $out .= n.'<option value="'.txpspecialchars($meta['code']).'"'. 645 (($meta['code'] == $cfg['site']['language_code']) ? ' selected="selected"' : ''). 646 '>'.txpspecialchars($meta['name']).'</option>'; 647 } 648 } 649 } 650 651 $out .= n.'</select>'. 652 n.'</div>'. 653 n.'</div>'; 654 655 return $out; 656 } 657 658 659 function check_config_txp($meter) 660 { 661 global $txpcfg, $cfg, $config_path; 662 if (!isset($txpcfg['db'])) { 663 if (!is_readable($config_path.DS.'config.php')) { 664 $problems[] = msg(gTxt('config_php_not_found', array( 665 '{file}' => txpspecialchars($config_path.DS.'config.php') 666 ), 'raw'), MSG_ERROR); 667 } else { 668 @include $config_path.DS.'config.php'; 669 } 670 } 671 672 if (!isset($txpcfg) 673 || ($txpcfg['db'] != $cfg['database']['db_name']) 674 || ($txpcfg['table_prefix'] != $cfg['database']['table_prefix']) 675 ) { 676 $problems[] = msg(gTxt('config_php_does_not_match_input', '', 'raw'), MSG_ERROR); 677 678 echo txp_setup_progress_meter($meter). 679 n.'<div class="txp-setup">'. 680 n.join(n, $problems). 681 setup_config_contents(). 682 n.'</div>'; 683 684 exit; 685 } 686 } 687 688 function check_config_exists() 689 { 690 global $txpcfg, $config_path; 691 692 if (!isset($txpcfg['db'])) { 693 @include $config_path.DS.'config.php'; 694 } 695 696 if (!empty($txpcfg['db'])) { 697 echo msg(gTxt('already_installed', array('{configpath}' => $config_path.DS)), MSG_ALERT, true); 698 } 699 } 700 701 /** 702 * Message box 703 * 704 */ 705 706 function msg($msg, $class = MSG_OK, $back = false) 707 { 708 global $cfg; 709 710 $icon = ($class == MSG_OK) ? 'ui-icon ui-icon-check' : 'ui-icon ui-icon-alert'; 711 $out = graf( 712 span(null, array('class' => $icon)).' '. 713 $msg, 714 array('class' => $class) 715 ); 716 717 if (! $back) { 718 return $out; 719 } 720 721 echo $out . setup_back_button().n.'</div>'; 722 $_SESSION['cfg'] = $cfg; 723 exit; 724 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
title