[ 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              try {
 107                  if(! (check_functions() && check_permissions()) ){
 108                      echo '<p>'.$lang['i_problems'].'</p>';
 109                      print_errors();
 110                      print_retry();
 111                  }elseif(!check_configs()){
 112                      echo '<p>'.$lang['i_modified'].'</p>';
 113                      print_errors();
 114                  }elseif(check_data($_REQUEST['d'])){
 115                      // check_data has sanitized all input parameters
 116                      if(!store_data($_REQUEST['d'])){
 117                          echo '<p>'.$lang['i_failure'].'</p>';
 118                          print_errors();
 119                      }else{
 120                          echo '<p>'.$lang['i_success'].'</p>';
 121                      }
 122                  }else{
 123                      print_errors();
 124                      print_form($_REQUEST['d']);
 125                  }
 126              } catch (Exception $e) {
 127                  echo 'Caught exception: ',  $e->getMessage(), "\n";
 128              }
 129          ?>
 130      </div>
 131  
 132  
 133  <div style="clear: both">
 134    <a href="http://dokuwiki.org/"><img src="lib/tpl/dokuwiki/images/button-dw.png" alt="driven by DokuWiki" /></a>
 135    <a href="http://php.net"><img src="lib/tpl/dokuwiki/images/button-php.gif" alt="powered by PHP" /></a>
 136  </div>
 137  </body>
 138  </html>
 139  <?php
 140  
 141  /**
 142   * Print the input form
 143   *
 144   * @param array $d submitted entry 'd' of request data
 145   */
 146  function print_form($d){
 147      global $lang;
 148      global $LC;
 149  
 150      include(DOKU_CONF.'license.php');
 151  
 152      if(!is_array($d)) $d = array();
 153      $d = array_map('hsc',$d);
 154  
 155      if(!isset($d['acl'])) $d['acl']=1;
 156      if(!isset($d['pop'])) $d['pop']=1;
 157  
 158      ?>
 159      <form action="" method="post">
 160      <input type="hidden" name="l" value="<?php echo $LC ?>" />
 161      <fieldset>
 162          <label for="title"><?php echo $lang['i_wikiname']?>
 163          <input type="text" name="d[title]" id="title" value="<?php echo $d['title'] ?>" style="width: 20em;" />
 164          </label>
 165  
 166          <fieldset style="margin-top: 1em;">
 167              <label for="acl">
 168              <input type="checkbox" name="d[acl]" id="acl" <?php echo(($d['acl'] ? ' checked="checked"' : ''));?> />
 169              <?php echo $lang['i_enableacl']?></label>
 170  
 171              <fieldset id="acldep">
 172                  <label for="superuser"><?php echo $lang['i_superuser']?></label>
 173                  <input class="text" type="text" name="d[superuser]" id="superuser" value="<?php echo $d['superuser'] ?>" />
 174  
 175                  <label for="fullname"><?php echo $lang['fullname']?></label>
 176                  <input class="text" type="text" name="d[fullname]" id="fullname" value="<?php echo $d['fullname'] ?>" />
 177  
 178                  <label for="email"><?php echo $lang['email']?></label>
 179                  <input class="text" type="text" name="d[email]" id="email" value="<?php echo $d['email'] ?>" />
 180  
 181                  <label for="password"><?php echo $lang['pass']?></label>
 182                  <input class="text" type="password" name="d[password]" id="password" />
 183  
 184                  <label for="confirm"><?php echo $lang['passchk']?></label>
 185                  <input class="text" type="password" name="d[confirm]" id="confirm" />
 186  
 187                  <label for="policy"><?php echo $lang['i_policy']?></label>
 188                  <select class="text" name="d[policy]" id="policy">
 189                      <option value="0" <?php echo ($d['policy'] == 0)?'selected="selected"':'' ?>><?php echo $lang['i_pol0']?></option>
 190                      <option value="1" <?php echo ($d['policy'] == 1)?'selected="selected"':'' ?>><?php echo $lang['i_pol1']?></option>
 191                      <option value="2" <?php echo ($d['policy'] == 2)?'selected="selected"':'' ?>><?php echo $lang['i_pol2']?></option>
 192                  </select>
 193  
 194                  <label for="allowreg">
 195                      <input type="checkbox" name="d[allowreg]" id="allowreg" <?php echo(($d['allowreg'] ? ' checked="checked"' : ''));?> />
 196                      <?php echo $lang['i_allowreg']?>
 197                  </label>
 198              </fieldset>
 199          </fieldset>
 200  
 201          <fieldset>
 202              <p><?php echo $lang['i_license']?></p>
 203              <?php
 204              array_push($license,array('name' => $lang['i_license_none'], 'url'=>''));
 205              if(empty($d['license'])) $d['license'] = 'cc-by-sa';
 206              foreach($license as $key => $lic){
 207                  echo '<label for="lic_'.$key.'">';
 208                  echo '<input type="radio" name="d[license]" value="'.hsc($key).'" id="lic_'.$key.'"'.
 209                       (($d['license'] === $key)?' checked="checked"':'').'>';
 210                  echo hsc($lic['name']);
 211                  if($lic['url']) echo ' <a href="'.$lic['url'].'" target="_blank"><sup>[?]</sup></a>';
 212                  echo '</label>';
 213              }
 214              ?>
 215          </fieldset>
 216  
 217          <fieldset>
 218              <p><?php echo $lang['i_pop_field']?></p>
 219              <label for="pop">
 220                  <input type="checkbox" name="d[pop]" id="pop" <?php echo(($d['pop'] ? ' checked="checked"' : ''));?> />
 221                  <?php echo $lang['i_pop_label']?> <a href="http://www.dokuwiki.org/popularity" target="_blank"><sup>[?]</sup></a>
 222              </label>
 223          </fieldset>
 224  
 225      </fieldset>
 226      <fieldset id="process">
 227          <button type="submit" name="submit"><?php echo $lang['btn_save']?></button>
 228      </fieldset>
 229      </form>
 230      <?php
 231  }
 232  
 233  function print_retry() {
 234      global $lang;
 235      global $LC;
 236      ?>
 237      <form action="" method="get">
 238        <fieldset>
 239          <input type="hidden" name="l" value="<?php echo $LC ?>" />
 240          <button type="submit"><?php echo $lang['i_retry'];?></button>
 241        </fieldset>
 242      </form>
 243      <?php
 244  }
 245  
 246  /**
 247   * Check validity of data
 248   *
 249   * @author Andreas Gohr
 250   *
 251   * @param array $d
 252   * @return bool ok?
 253   */
 254  function check_data(&$d){
 255      static $form_default = array(
 256          'title'     => '',
 257          'acl'       => '1',
 258          'superuser' => '',
 259          'fullname'  => '',
 260          'email'     => '',
 261          'password'  => '',
 262          'confirm'   => '',
 263          'policy'    => '0',
 264          'allowreg'  => '0',
 265          'license'   => 'cc-by-sa'
 266      );
 267      global $lang;
 268      global $error;
 269  
 270      if(!is_array($d)) $d = array();
 271      foreach($d as $k => $v) {
 272          if(is_array($v))
 273              unset($d[$k]);
 274          else
 275              $d[$k] = (string)$v;
 276      }
 277  
 278      //autolowercase the username
 279      $d['superuser'] = isset($d['superuser']) ? strtolower($d['superuser']) : "";
 280  
 281      $ok = false;
 282  
 283      if(isset($_REQUEST['submit'])) {
 284          $ok = true;
 285  
 286          // check input
 287          if(empty($d['title'])){
 288              $error[] = sprintf($lang['i_badval'],$lang['i_wikiname']);
 289              $ok      = false;
 290          }
 291          if(isset($d['acl'])){
 292              if(!preg_match('/^[a-z0-9_]+$/',$d['superuser'])){
 293                  $error[] = sprintf($lang['i_badval'],$lang['i_superuser']);
 294                  $ok      = false;
 295              }
 296              if(empty($d['password'])){
 297                  $error[] = sprintf($lang['i_badval'],$lang['pass']);
 298                  $ok      = false;
 299              }
 300              elseif(!isset($d['confirm']) || $d['confirm'] != $d['password']){
 301                  $error[] = sprintf($lang['i_badval'],$lang['passchk']);
 302                  $ok      = false;
 303              }
 304              if(empty($d['fullname']) || strstr($d['fullname'],':')){
 305                  $error[] = sprintf($lang['i_badval'],$lang['fullname']);
 306                  $ok      = false;
 307              }
 308              if(empty($d['email']) || strstr($d['email'],':') || !strstr($d['email'],'@')){
 309                  $error[] = sprintf($lang['i_badval'],$lang['email']);
 310                  $ok      = false;
 311              }
 312          }
 313      }
 314      $d = array_merge($form_default, $d);
 315      return $ok;
 316  }
 317  
 318  /**
 319   * Writes the data to the config files
 320   *
 321   * @author  Chris Smith <chris@jalakai.co.uk>
 322   *
 323   * @param array $d
 324   * @return bool
 325   */
 326  function store_data($d){
 327      global $LC;
 328      $ok = true;
 329      $d['policy'] = (int) $d['policy'];
 330  
 331      // create local.php
 332      $now    = gmdate('r');
 333      $output = <<<EOT
 334  <?php
 335  /**
 336   * Dokuwiki's Main Configuration File - Local Settings
 337   * Auto-generated by install script
 338   * Date: $now
 339   */
 340  
 341  EOT;
 342      // add any config options set by a previous installer
 343      $preset = __DIR__.'/install.conf';
 344      if(file_exists($preset)){
 345          $output .= "# preset config options\n";
 346          $output .= file_get_contents($preset);
 347          $output .= "\n\n";
 348          $output .= "# options selected in installer\n";
 349          @unlink($preset);
 350      }
 351  
 352      $output .= '$conf[\'title\'] = \''.addslashes($d['title'])."';\n";
 353      $output .= '$conf[\'lang\'] = \''.addslashes($LC)."';\n";
 354      $output .= '$conf[\'license\'] = \''.addslashes($d['license'])."';\n";
 355      if($d['acl']){
 356          $output .= '$conf[\'useacl\'] = 1'.";\n";
 357          $output .= "\$conf['superuser'] = '@admin';\n";
 358      }
 359      if(!$d['allowreg']){
 360          $output .= '$conf[\'disableactions\'] = \'register\''.";\n";
 361      }
 362      $ok = $ok && fileWrite(DOKU_LOCAL.'local.php',$output);
 363  
 364      if ($d['acl']) {
 365          // hash the password
 366          $phash = new PassHash();
 367          $pass = $phash->hash_smd5($d['password']);
 368  
 369          // create users.auth.php
 370          // --- user:SMD5password:Real Name:email:groups,comma,seperated
 371          $output = join(":",array($d['superuser'], $pass, $d['fullname'], $d['email'], 'admin,user'));
 372          $output = @file_get_contents(DOKU_CONF.'users.auth.php.dist')."\n$output\n";
 373          $ok = $ok && fileWrite(DOKU_LOCAL.'users.auth.php', $output);
 374  
 375          // create acl.auth.php
 376          $output = <<<EOT
 377  # acl.auth.php
 378  # <?php exit()?>
 379  # Don't modify the lines above
 380  #
 381  # Access Control Lists
 382  #
 383  # Auto-generated by install script
 384  # Date: $now
 385  
 386  EOT;
 387          if($d['policy'] == 2){
 388              $output .=  "*               @ALL          0\n";
 389              $output .=  "*               @user         8\n";
 390          }elseif($d['policy'] == 1){
 391              $output .=  "*               @ALL          1\n";
 392              $output .=  "*               @user         8\n";
 393          }else{
 394              $output .=  "*               @ALL          8\n";
 395          }
 396          $ok = $ok && fileWrite(DOKU_LOCAL.'acl.auth.php', $output);
 397      }
 398  
 399      // enable popularity submission
 400      if($d['pop']){
 401          @touch(DOKU_INC.'data/cache/autosubmit.txt');
 402      }
 403  
 404      // disable auth plugins til needed
 405      $output = <<<EOT
 406  <?php
 407  /*
 408   * Local plugin enable/disable settings
 409   *
 410   * Auto-generated by install script
 411   * Date: $now
 412   */
 413  
 414  \$plugins['authad']    = 0;
 415  \$plugins['authldap']  = 0;
 416  \$plugins['authmysql'] = 0;
 417  \$plugins['authpgsql'] = 0;
 418  
 419  EOT;
 420      $ok = $ok && fileWrite(DOKU_LOCAL.'plugins.local.php', $output);
 421  
 422      return $ok;
 423  }
 424  
 425  /**
 426   * Write the given content to a file
 427   *
 428   * @author  Chris Smith <chris@jalakai.co.uk>
 429   *
 430   * @param string $filename
 431   * @param string $data
 432   * @return bool
 433   */
 434  function fileWrite($filename, $data) {
 435      global $error;
 436      global $lang;
 437  
 438      if (($fp = @fopen($filename, 'wb')) === false) {
 439          $filename = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}/', $filename);
 440          $error[]  = sprintf($lang['i_writeerr'],$filename);
 441          return false;
 442      }
 443  
 444      if (!empty($data)) { fwrite($fp, $data);  }
 445      fclose($fp);
 446      return true;
 447  }
 448  
 449  
 450  /**
 451   * check installation dependent local config files and tests for a known
 452   * unmodified main config file
 453   *
 454   * @author      Chris Smith <chris@jalakai.co.uk>
 455   *
 456   * @return bool
 457   */
 458  function check_configs(){
 459      global $error;
 460      global $lang;
 461  
 462      $ok = true;
 463  
 464      $config_files = array(
 465          'local' => DOKU_LOCAL.'local.php',
 466          'users' => DOKU_LOCAL.'users.auth.php',
 467          'auth'  => DOKU_LOCAL.'acl.auth.php'
 468      );
 469  
 470      // configs shouldn't exist
 471      foreach ($config_files as $file) {
 472          if (file_exists($file) && filesize($file)) {
 473              $file    = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}/', $file);
 474              $error[] = sprintf($lang['i_confexists'],$file);
 475              $ok      = false;
 476          }
 477      }
 478      return $ok;
 479  }
 480  
 481  
 482  /**
 483   * Check other installation dir/file permission requirements
 484   *
 485   * @author      Chris Smith <chris@jalakai.co.uk>
 486   *
 487   * @return bool
 488   */
 489  function check_permissions(){
 490      global $error;
 491      global $lang;
 492  
 493      $dirs = array(
 494          'conf'        => DOKU_LOCAL,
 495          'data'        => DOKU_INC.'data',
 496          'pages'       => DOKU_INC.'data/pages',
 497          'attic'       => DOKU_INC.'data/attic',
 498          'media'       => DOKU_INC.'data/media',
 499          'media_attic' => DOKU_INC.'data/media_attic',
 500          'media_meta'  => DOKU_INC.'data/media_meta',
 501          'meta'        => DOKU_INC.'data/meta',
 502          'cache'       => DOKU_INC.'data/cache',
 503          'locks'       => DOKU_INC.'data/locks',
 504          'index'       => DOKU_INC.'data/index',
 505          'tmp'         => DOKU_INC.'data/tmp'
 506      );
 507  
 508      $ok = true;
 509      foreach($dirs as $dir){
 510          if(!file_exists("$dir/.") || !is_writable($dir)){
 511              $dir     = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}', $dir);
 512              $error[] = sprintf($lang['i_permfail'],$dir);
 513              $ok      = false;
 514          }
 515      }
 516      return $ok;
 517  }
 518  
 519  /**
 520   * Check the availability of functions used in DokuWiki and the PHP version
 521   *
 522   * @author Andreas Gohr <andi@splitbrain.org>
 523   *
 524   * @return bool
 525   */
 526  function check_functions(){
 527      global $error;
 528      global $lang;
 529      $ok = true;
 530  
 531      if(version_compare(phpversion(),'5.6.0','<')){
 532          $error[] = sprintf($lang['i_phpver'],phpversion(),'5.6.0');
 533          $ok = false;
 534      }
 535  
 536      if(ini_get('mbstring.func_overload') != 0){
 537          $error[] = $lang['i_mbfuncoverload'];
 538          $ok = false;
 539      }
 540  
 541      $funcs = explode(' ','addslashes call_user_func chmod copy fgets '.
 542                           'file file_exists fseek flush filesize ftell fopen '.
 543                           'glob header ignore_user_abort ini_get mail mkdir '.
 544                           'ob_start opendir parse_ini_file readfile realpath '.
 545                           'rename rmdir serialize session_start unlink usleep '.
 546                           'preg_replace file_get_contents htmlspecialchars_decode '.
 547                           'spl_autoload_register stream_select fsockopen pack');
 548  
 549      if (!function_exists('mb_substr')) {
 550          $funcs[] = 'utf8_encode';
 551          $funcs[] = 'utf8_decode';
 552      }
 553  
 554      foreach($funcs as $func){
 555          if(!function_exists($func)){
 556              $error[] = sprintf($lang['i_funcna'],$func);
 557              $ok = false;
 558          }
 559      }
 560      return $ok;
 561  }
 562  
 563  /**
 564   * Print language selection
 565   *
 566   * @author Andreas Gohr <andi@splitbrain.org>
 567   */
 568  function langsel(){
 569      global $lang;
 570      global $LC;
 571  
 572      $dir = DOKU_INC.'inc/lang';
 573      $dh  = opendir($dir);
 574      if(!$dh) return;
 575  
 576      $langs = array();
 577      while (($file = readdir($dh)) !== false) {
 578          if(preg_match('/^[\._]/',$file)) continue;
 579          if(is_dir($dir.'/'.$file) && file_exists($dir.'/'.$file.'/lang.php')){
 580              $langs[] = $file;
 581          }
 582      }
 583      closedir($dh);
 584      sort($langs);
 585  
 586      echo '<form action="">';
 587      echo $lang['i_chooselang'];
 588      echo ': <select name="l" onchange="submit()">';
 589      foreach($langs as $l){
 590          $sel = ($l == $LC) ? 'selected="selected"' : '';
 591          echo '<option value="'.$l.'" '.$sel.'>'.$l.'</option>';
 592      }
 593      echo '</select> ';
 594      echo '<button type="submit">'.$lang['btn_update'].'</button>';
 595      echo '</form>';
 596  }
 597  
 598  /**
 599   * Print global error array
 600   *
 601   * @author Andreas Gohr <andi@splitbrain.org>
 602   */
 603  function print_errors(){
 604      global $error;
 605      if(!empty($error)) {
 606          echo '<ul>';
 607          foreach ($error as $err){
 608              echo "<li>$err</li>";
 609          }
 610          echo '</ul>';
 611      }
 612  }