[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/ -> install.php (source)

   1  <?php
   2  /*><div style="width:60%; margin: auto; background-color: #fcc;
   3                  border: 1px solid #faa; padding: 0.5em 1em;">
   4      <h1 style="font-size: 120%">No PHP Support</h1>
   5  
   6      It seems this server has no PHP support enabled. You will need to
   7      enable PHP before you can install and run DokuWiki. Contact your hosting
   8      provider if you're unsure what this means.
   9  
  10  </div>*/
  11  /**
  12   * Dokuwiki installation assistance
  13   *
  14   * @author      Chris Smith <chris@jalakai.co.uk>
  15   */
  16  
  17  if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/');
  18  if(!defined('DOKU_CONF')) define('DOKU_CONF',DOKU_INC.'conf/');
  19  if(!defined('DOKU_LOCAL')) define('DOKU_LOCAL',DOKU_INC.'conf/');
  20  
  21  // load and initialize the core system
  22  require_once (DOKU_INC.'inc/init.php');
  23  
  24  // check for error reporting override or set error reporting to sane values
  25  if (!defined('DOKU_E_LEVEL')) { error_reporting(E_ALL ^ E_NOTICE); }
  26  else { error_reporting(DOKU_E_LEVEL); }
  27  
  28  // language strings
  29  require_once (DOKU_INC.'inc/lang/en/lang.php');
  30  if(isset($_REQUEST['l']) && !is_array($_REQUEST['l'])) {
  31      $LC = preg_replace('/[^a-z\-]+/','',$_REQUEST['l']);
  32  }
  33  if(empty($LC)) $LC = 'en';
  34  if($LC && $LC != 'en' ) {
  35      require_once(DOKU_INC.'inc/lang/'.$LC.'/lang.php');
  36  }
  37  
  38  // initialise variables ...
  39  $error = array();
  40  
  41  // begin output
  42  header('Content-Type: text/html; charset=utf-8');
  43  ?>
  44  <!DOCTYPE html>
  45  <html lang="<?php echo $LC?>" dir="<?php echo $lang['direction']?>">
  46  <head>
  47      <meta charset="utf-8" />
  48      <title><?php echo $lang['i_installer']?></title>
  49      <style type="text/css">
  50          body { width: 90%; margin: 0 auto; font: 84% Verdana, Helvetica, Arial, sans-serif; }
  51          img { border: none }
  52          br.cl { clear:both; }
  53          code { font-size: 110%; color: #800000; }
  54          fieldset { border: none }
  55          label { display: block; margin-top: 0.5em; }
  56          select.text, input.text { width: 30em; margin: 0 0.5em; }
  57          a {text-decoration: none}
  58      </style>
  59      <script type="text/javascript">
  60          function acltoggle(){
  61              var cb = document.getElementById('acl');
  62              var fs = document.getElementById('acldep');
  63              if(!cb || !fs) return;
  64              if(cb.checked){
  65                  fs.style.display = '';
  66              }else{
  67                  fs.style.display = 'none';
  68              }
  69          }
  70          window.onload = function(){
  71              acltoggle();
  72              var cb = document.getElementById('acl');
  73              if(cb) cb.onchange = acltoggle;
  74          };
  75      </script>
  76  </head>
  77  <body style="">
  78      <h1 style="float:left">
  79          <img src="lib/exe/fetch.php?media=wiki:dokuwiki-128.png"
  80               style="vertical-align: middle;" alt="" height="64" width="64" />
  81          <?php echo $lang['i_installer']?>
  82      </h1>
  83      <div style="float:right; margin: 1em;">
  84          <?php langsel()?>
  85      </div>
  86      <br class="cl" />
  87  
  88      <div style="float: right; width: 34%;">
  89          <?php
  90              if(file_exists(DOKU_INC.'inc/lang/'.$LC.'/install.html')){
  91                  include(DOKU_INC.'inc/lang/'.$LC.'/install.html');
  92              }else{
  93                  print "<div lang=\"en\" dir=\"ltr\">\n";
  94                  include(DOKU_INC.'inc/lang/en/install.html');
  95                  print "</div>\n";
  96              }
  97          ?>
  98          <a style="background: transparent url(data/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png) left top no-repeat;
  99                    display: block; width:380px; height:73px; border:none; clear:both;"
 100             target="_blank"
 101             href="http://www.dokuwiki.org/security#web_access_security"></a>
 102      </div>
 103  
 104      <div style="float: left; width: 58%;">
 105          <?php
 106              if(! (check_functions() && check_permissions()) ){
 107                  echo '<p>'.$lang['i_problems'].'</p>';
 108                  print_errors();
 109                  print_retry();
 110              }elseif(!check_configs()){
 111                  echo '<p>'.$lang['i_modified'].'</p>';
 112                  print_errors();
 113              }elseif(check_data($_REQUEST['d'])){
 114                  // check_data has sanitized all input parameters
 115                  if(!store_data($_REQUEST['d'])){
 116                      echo '<p>'.$lang['i_failure'].'</p>';
 117                      print_errors();
 118                  }else{
 119                      echo '<p>'.$lang['i_success'].'</p>';
 120                  }
 121              }else{
 122                  print_errors();
 123                  print_form($_REQUEST['d']);
 124              }
 125          ?>
 126      </div>
 127  
 128  
 129  <div style="clear: both">
 130    <a href="http://dokuwiki.org/"><img src="lib/tpl/dokuwiki/images/button-dw.png" alt="driven by DokuWiki" /></a>
 131    <a href="http://php.net"><img src="lib/tpl/dokuwiki/images/button-php.gif" alt="powered by PHP" /></a>
 132  </div>
 133  </body>
 134  </html>
 135  <?php
 136  
 137  /**
 138   * Print the input form
 139   *
 140   * @param array $d submitted entry 'd' of request data
 141   */
 142  function print_form($d){
 143      global $lang;
 144      global $LC;
 145  
 146      include(DOKU_CONF.'license.php');
 147  
 148      if(!is_array($d)) $d = array();
 149      $d = array_map('hsc',$d);
 150  
 151      if(!isset($d['acl'])) $d['acl']=1;
 152      if(!isset($d['pop'])) $d['pop']=1;
 153  
 154      ?>
 155      <form action="" method="post">
 156      <input type="hidden" name="l" value="<?php echo $LC ?>" />
 157      <fieldset>
 158          <label for="title"><?php echo $lang['i_wikiname']?>
 159          <input type="text" name="d[title]" id="title" value="<?php echo $d['title'] ?>" style="width: 20em;" />
 160          </label>
 161  
 162          <fieldset style="margin-top: 1em;">
 163              <label for="acl">
 164              <input type="checkbox" name="d[acl]" id="acl" <?php echo(($d['acl'] ? ' checked="checked"' : ''));?> />
 165              <?php echo $lang['i_enableacl']?></label>
 166  
 167              <fieldset id="acldep">
 168                  <label for="superuser"><?php echo $lang['i_superuser']?></label>
 169                  <input class="text" type="text" name="d[superuser]" id="superuser" value="<?php echo $d['superuser'] ?>" />
 170  
 171                  <label for="fullname"><?php echo $lang['fullname']?></label>
 172                  <input class="text" type="text" name="d[fullname]" id="fullname" value="<?php echo $d['fullname'] ?>" />
 173  
 174                  <label for="email"><?php echo $lang['email']?></label>
 175                  <input class="text" type="text" name="d[email]" id="email" value="<?php echo $d['email'] ?>" />
 176  
 177                  <label for="password"><?php echo $lang['pass']?></label>
 178                  <input class="text" type="password" name="d[password]" id="password" />
 179  
 180                  <label for="confirm"><?php echo $lang['passchk']?></label>
 181                  <input class="text" type="password" name="d[confirm]" id="confirm" />
 182  
 183                  <label for="policy"><?php echo $lang['i_policy']?></label>
 184                  <select class="text" name="d[policy]" id="policy">
 185                      <option value="0" <?php echo ($d['policy'] == 0)?'selected="selected"':'' ?>><?php echo $lang['i_pol0']?></option>
 186                      <option value="1" <?php echo ($d['policy'] == 1)?'selected="selected"':'' ?>><?php echo $lang['i_pol1']?></option>
 187                      <option value="2" <?php echo ($d['policy'] == 2)?'selected="selected"':'' ?>><?php echo $lang['i_pol2']?></option>
 188                  </select>
 189  
 190                  <label for="allowreg">
 191                      <input type="checkbox" name="d[allowreg]" id="allowreg" <?php echo(($d['allowreg'] ? ' checked="checked"' : ''));?> />
 192                      <?php echo $lang['i_allowreg']?>
 193                  </label>
 194              </fieldset>
 195          </fieldset>
 196  
 197          <fieldset>
 198              <p><?php echo $lang['i_license']?></p>
 199              <?php
 200              array_push($license,array('name' => $lang['i_license_none'], 'url'=>''));
 201              if(empty($d['license'])) $d['license'] = 'cc-by-sa';
 202              foreach($license as $key => $lic){
 203                  echo '<label for="lic_'.$key.'">';
 204                  echo '<input type="radio" name="d[license]" value="'.hsc($key).'" id="lic_'.$key.'"'.
 205                       (($d['license'] === $key)?' checked="checked"':'').'>';
 206                  echo hsc($lic['name']);
 207                  if($lic['url']) echo ' <a href="'.$lic['url'].'" target="_blank"><sup>[?]</sup></a>';
 208                  echo '</label>';
 209              }
 210              ?>
 211          </fieldset>
 212  
 213          <fieldset>
 214              <p><?php echo $lang['i_pop_field']?></p>
 215              <label for="pop">
 216                  <input type="checkbox" name="d[pop]" id="pop" <?php echo(($d['pop'] ? ' checked="checked"' : ''));?> />
 217                  <?php echo $lang['i_pop_label']?> <a href="http://www.dokuwiki.org/popularity" target="_blank"><sup>[?]</sup></a>
 218              </label>
 219          </fieldset>
 220  
 221      </fieldset>
 222      <fieldset id="process">
 223          <button type="submit" name="submit"><?php echo $lang['btn_save']?></button>
 224      </fieldset>
 225      </form>
 226      <?php
 227  }
 228  
 229  function print_retry() {
 230      global $lang;
 231      global $LC;
 232      ?>
 233      <form action="" method="get">
 234        <fieldset>
 235          <input type="hidden" name="l" value="<?php echo $LC ?>" />
 236          <button type="submit"><?php echo $lang['i_retry'];?></button>
 237        </fieldset>
 238      </form>
 239      <?php
 240  }
 241  
 242  /**
 243   * Check validity of data
 244   *
 245   * @author Andreas Gohr
 246   *
 247   * @param array $d
 248   * @return bool ok?
 249   */
 250  function check_data(&$d){
 251      static $form_default = array(
 252          'title'     => '',
 253          'acl'       => '1',
 254          'superuser' => '',
 255          'fullname'  => '',
 256          'email'     => '',
 257          'password'  => '',
 258          'confirm'   => '',
 259          'policy'    => '0',
 260          'allowreg'  => '0',
 261          'license'   => 'cc-by-sa'
 262      );
 263      global $lang;
 264      global $error;
 265  
 266      if(!is_array($d)) $d = array();
 267      foreach($d as $k => $v) {
 268          if(is_array($v))
 269              unset($d[$k]);
 270          else
 271              $d[$k] = (string)$v;
 272      }
 273  
 274      //autolowercase the username
 275      $d['superuser'] = isset($d['superuser']) ? strtolower($d['superuser']) : "";
 276  
 277      $ok = false;
 278  
 279      if(isset($_REQUEST['submit'])) {
 280          $ok = true;
 281  
 282          // check input
 283          if(empty($d['title'])){
 284              $error[] = sprintf($lang['i_badval'],$lang['i_wikiname']);
 285              $ok      = false;
 286          }
 287          if(isset($d['acl'])){
 288              if(!preg_match('/^[a-z0-9_]+$/',$d['superuser'])){
 289                  $error[] = sprintf($lang['i_badval'],$lang['i_superuser']);
 290                  $ok      = false;
 291              }
 292              if(empty($d['password'])){
 293                  $error[] = sprintf($lang['i_badval'],$lang['pass']);
 294                  $ok      = false;
 295              }
 296              elseif(!isset($d['confirm']) || $d['confirm'] != $d['password']){
 297                  $error[] = sprintf($lang['i_badval'],$lang['passchk']);
 298                  $ok      = false;
 299              }
 300              if(empty($d['fullname']) || strstr($d['fullname'],':')){
 301                  $error[] = sprintf($lang['i_badval'],$lang['fullname']);
 302                  $ok      = false;
 303              }
 304              if(empty($d['email']) || strstr($d['email'],':') || !strstr($d['email'],'@')){
 305                  $error[] = sprintf($lang['i_badval'],$lang['email']);
 306                  $ok      = false;
 307              }
 308          }
 309      }
 310      $d = array_merge($form_default, $d);
 311      return $ok;
 312  }
 313  
 314  /**
 315   * Writes the data to the config files
 316   *
 317   * @author  Chris Smith <chris@jalakai.co.uk>
 318   *
 319   * @param array $d
 320   * @return bool
 321   */
 322  function store_data($d){
 323      global $LC;
 324      $ok = true;
 325      $d['policy'] = (int) $d['policy'];
 326  
 327      // create local.php
 328      $now    = gmdate('r');
 329      $output = <<<EOT
 330  <?php
 331  /**
 332   * Dokuwiki's Main Configuration File - Local Settings
 333   * Auto-generated by install script
 334   * Date: $now
 335   */
 336  
 337  EOT;
 338      // add any config options set by a previous installer
 339      $preset = __DIR__.'/install.conf';
 340      if(file_exists($preset)){
 341          $output .= "# preset config options\n";
 342          $output .= file_get_contents($preset);
 343          $output .= "\n\n";
 344          $output .= "# options selected in installer\n";
 345          @unlink($preset);
 346      }
 347  
 348      $output .= '$conf[\'title\'] = \''.addslashes($d['title'])."';\n";
 349      $output .= '$conf[\'lang\'] = \''.addslashes($LC)."';\n";
 350      $output .= '$conf[\'license\'] = \''.addslashes($d['license'])."';\n";
 351      if($d['acl']){
 352          $output .= '$conf[\'useacl\'] = 1'.";\n";
 353          $output .= "\$conf['superuser'] = '@admin';\n";
 354      }
 355      if(!$d['allowreg']){
 356          $output .= '$conf[\'disableactions\'] = \'register\''.";\n";
 357      }
 358      $ok = $ok && fileWrite(DOKU_LOCAL.'local.php',$output);
 359  
 360      if ($d['acl']) {
 361          // hash the password
 362          $phash = new PassHash();
 363          $pass = $phash->hash_smd5($d['password']);
 364  
 365          // create users.auth.php
 366          // --- user:SMD5password:Real Name:email:groups,comma,seperated
 367          $output = join(":",array($d['superuser'], $pass, $d['fullname'], $d['email'], 'admin,user'));
 368          $output = @file_get_contents(DOKU_CONF.'users.auth.php.dist')."\n$output\n";
 369          $ok = $ok && fileWrite(DOKU_LOCAL.'users.auth.php', $output);
 370  
 371          // create acl.auth.php
 372          $output = <<<EOT
 373  # acl.auth.php
 374  # <?php exit()?>
 375  # Don't modify the lines above
 376  #
 377  # Access Control Lists
 378  #
 379  # Auto-generated by install script
 380  # Date: $now
 381  
 382  EOT;
 383          if($d['policy'] == 2){
 384              $output .=  "*               @ALL          0\n";
 385              $output .=  "*               @user         8\n";
 386          }elseif($d['policy'] == 1){
 387              $output .=  "*               @ALL          1\n";
 388              $output .=  "*               @user         8\n";
 389          }else{
 390              $output .=  "*               @ALL          8\n";
 391          }
 392          $ok = $ok && fileWrite(DOKU_LOCAL.'acl.auth.php', $output);
 393      }
 394  
 395      // enable popularity submission
 396      if($d['pop']){
 397          @touch(DOKU_INC.'data/cache/autosubmit.txt');
 398      }
 399  
 400      // disable auth plugins til needed
 401      $output = <<<EOT
 402  <?php
 403  /*
 404   * Local plugin enable/disable settings
 405   *
 406   * Auto-generated by install script
 407   * Date: $now
 408   */
 409  
 410  \$plugins['authad']    = 0;
 411  \$plugins['authldap']  = 0;
 412  \$plugins['authmysql'] = 0;
 413  \$plugins['authpgsql'] = 0;
 414  
 415  EOT;
 416      $ok = $ok && fileWrite(DOKU_LOCAL.'plugins.local.php', $output);
 417  
 418      return $ok;
 419  }
 420  
 421  /**
 422   * Write the given content to a file
 423   *
 424   * @author  Chris Smith <chris@jalakai.co.uk>
 425   *
 426   * @param string $filename
 427   * @param string $data
 428   * @return bool
 429   */
 430  function fileWrite($filename, $data) {
 431      global $error;
 432      global $lang;
 433  
 434      if (($fp = @fopen($filename, 'wb')) === false) {
 435          $filename = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}/', $filename);
 436          $error[]  = sprintf($lang['i_writeerr'],$filename);
 437          return false;
 438      }
 439  
 440      if (!empty($data)) { fwrite($fp, $data);  }
 441      fclose($fp);
 442      return true;
 443  }
 444  
 445  
 446  /**
 447   * check installation dependent local config files and tests for a known
 448   * unmodified main config file
 449   *
 450   * @author      Chris Smith <chris@jalakai.co.uk>
 451   *
 452   * @return bool
 453   */
 454  function check_configs(){
 455      global $error;
 456      global $lang;
 457  
 458      $ok = true;
 459  
 460      $config_files = array(
 461          'local' => DOKU_LOCAL.'local.php',
 462          'users' => DOKU_LOCAL.'users.auth.php',
 463          'auth'  => DOKU_LOCAL.'acl.auth.php'
 464      );
 465  
 466      // configs shouldn't exist
 467      foreach ($config_files as $file) {
 468          if (file_exists($file) && filesize($file)) {
 469              $file    = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}/', $file);
 470              $error[] = sprintf($lang['i_confexists'],$file);
 471              $ok      = false;
 472          }
 473      }
 474      return $ok;
 475  }
 476  
 477  
 478  /**
 479   * Check other installation dir/file permission requirements
 480   *
 481   * @author      Chris Smith <chris@jalakai.co.uk>
 482   *
 483   * @return bool
 484   */
 485  function check_permissions(){
 486      global $error;
 487      global $lang;
 488  
 489      $dirs = array(
 490          'conf'        => DOKU_LOCAL,
 491          'data'        => DOKU_INC.'data',
 492          'pages'       => DOKU_INC.'data/pages',
 493          'attic'       => DOKU_INC.'data/attic',
 494          'media'       => DOKU_INC.'data/media',
 495          'media_attic' => DOKU_INC.'data/media_attic',
 496          'media_meta'  => DOKU_INC.'data/media_meta',
 497          'meta'        => DOKU_INC.'data/meta',
 498          'cache'       => DOKU_INC.'data/cache',
 499          'locks'       => DOKU_INC.'data/locks',
 500          'index'       => DOKU_INC.'data/index',
 501          'tmp'         => DOKU_INC.'data/tmp'
 502      );
 503  
 504      $ok = true;
 505      foreach($dirs as $dir){
 506          if(!file_exists("$dir/.") || !is_writable($dir)){
 507              $dir     = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}', $dir);
 508              $error[] = sprintf($lang['i_permfail'],$dir);
 509              $ok      = false;
 510          }
 511      }
 512      return $ok;
 513  }
 514  
 515  /**
 516   * Check the availability of functions used in DokuWiki and the PHP version
 517   *
 518   * @author Andreas Gohr <andi@splitbrain.org>
 519   *
 520   * @return bool
 521   */
 522  function check_functions(){
 523      global $error;
 524      global $lang;
 525      $ok = true;
 526  
 527      if(version_compare(phpversion(),'5.6.0','<')){
 528          $error[] = sprintf($lang['i_phpver'],phpversion(),'5.6.0');
 529          $ok = false;
 530      }
 531  
 532      if(ini_get('mbstring.func_overload') != 0){
 533          $error[] = $lang['i_mbfuncoverload'];
 534          $ok = false;
 535      }
 536  
 537      $funcs = explode(' ','addslashes call_user_func chmod copy fgets '.
 538                           'file file_exists fseek flush filesize ftell fopen '.
 539                           'glob header ignore_user_abort ini_get mail mkdir '.
 540                           'ob_start opendir parse_ini_file readfile realpath '.
 541                           'rename rmdir serialize session_start unlink usleep '.
 542                           'preg_replace file_get_contents htmlspecialchars_decode '.
 543                           'spl_autoload_register stream_select fsockopen pack');
 544  
 545      if (!function_exists('mb_substr')) {
 546          $funcs[] = 'utf8_encode';
 547          $funcs[] = 'utf8_decode';
 548      }
 549  
 550      foreach($funcs as $func){
 551          if(!function_exists($func)){
 552              $error[] = sprintf($lang['i_funcna'],$func);
 553              $ok = false;
 554          }
 555      }
 556      return $ok;
 557  }
 558  
 559  /**
 560   * Print language selection
 561   *
 562   * @author Andreas Gohr <andi@splitbrain.org>
 563   */
 564  function langsel(){
 565      global $lang;
 566      global $LC;
 567  
 568      $dir = DOKU_INC.'inc/lang';
 569      $dh  = opendir($dir);
 570      if(!$dh) return;
 571  
 572      $langs = array();
 573      while (($file = readdir($dh)) !== false) {
 574          if(preg_match('/^[\._]/',$file)) continue;
 575          if(is_dir($dir.'/'.$file) && file_exists($dir.'/'.$file.'/lang.php')){
 576              $langs[] = $file;
 577          }
 578      }
 579      closedir($dh);
 580      sort($langs);
 581  
 582      echo '<form action="">';
 583      echo $lang['i_chooselang'];
 584      echo ': <select name="l" onchange="submit()">';
 585      foreach($langs as $l){
 586          $sel = ($l == $LC) ? 'selected="selected"' : '';
 587          echo '<option value="'.$l.'" '.$sel.'>'.$l.'</option>';
 588      }
 589      echo '</select> ';
 590      echo '<button type="submit">'.$lang['btn_update'].'</button>';
 591      echo '</form>';
 592  }
 593  
 594  /**
 595   * Print global error array
 596   *
 597   * @author Andreas Gohr <andi@splitbrain.org>
 598   */
 599  function print_errors(){
 600      global $error;
 601      if(!empty($error)) {
 602          echo '<ul>';
 603          foreach ($error as $err){
 604              echo "<li>$err</li>";
 605          }
 606          echo '</ul>';
 607      }
 608  }