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