[ 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          }else{
 313              // Since default = 1, browser won't send acl=0 when user untick acl
 314              $d['acl'] = '0';
 315          }
 316      }
 317      $d = array_merge($form_default, $d);
 318      return $ok;
 319  }
 320  
 321  /**
 322   * Writes the data to the config files
 323   *
 324   * @author  Chris Smith <chris@jalakai.co.uk>
 325   *
 326   * @param array $d
 327   * @return bool
 328   */
 329  function store_data($d){
 330      global $LC;
 331      $ok = true;
 332      $d['policy'] = (int) $d['policy'];
 333  
 334      // create local.php
 335      $now    = gmdate('r');
 336      $output = <<<EOT
 337  <?php
 338  /**
 339   * Dokuwiki's Main Configuration File - Local Settings
 340   * Auto-generated by install script
 341   * Date: $now
 342   */
 343  
 344  EOT;
 345      // add any config options set by a previous installer
 346      $preset = __DIR__.'/install.conf';
 347      if(file_exists($preset)){
 348          $output .= "# preset config options\n";
 349          $output .= file_get_contents($preset);
 350          $output .= "\n\n";
 351          $output .= "# options selected in installer\n";
 352          @unlink($preset);
 353      }
 354  
 355      $output .= '$conf[\'title\'] = \''.addslashes($d['title'])."';\n";
 356      $output .= '$conf[\'lang\'] = \''.addslashes($LC)."';\n";
 357      $output .= '$conf[\'license\'] = \''.addslashes($d['license'])."';\n";
 358      if($d['acl']){
 359          $output .= '$conf[\'useacl\'] = 1'.";\n";
 360          $output .= "\$conf['superuser'] = '@admin';\n";
 361      }
 362      if(!$d['allowreg']){
 363          $output .= '$conf[\'disableactions\'] = \'register\''.";\n";
 364      }
 365      $ok = $ok && fileWrite(DOKU_LOCAL.'local.php',$output);
 366  
 367      if ($d['acl']) {
 368          // hash the password
 369          $phash = new PassHash();
 370          $pass = $phash->hash_smd5($d['password']);
 371  
 372          // create users.auth.php
 373          // --- user:SMD5password:Real Name:email:groups,comma,seperated
 374          $output = join(":",array($d['superuser'], $pass, $d['fullname'], $d['email'], 'admin,user'));
 375          $output = @file_get_contents(DOKU_CONF.'users.auth.php.dist')."\n$output\n";
 376          $ok = $ok && fileWrite(DOKU_LOCAL.'users.auth.php', $output);
 377  
 378          // create acl.auth.php
 379          $output = <<<EOT
 380  # acl.auth.php
 381  # <?php exit()?>
 382  # Don't modify the lines above
 383  #
 384  # Access Control Lists
 385  #
 386  # Auto-generated by install script
 387  # Date: $now
 388  
 389  EOT;
 390          if($d['policy'] == 2){
 391              $output .=  "*               @ALL          0\n";
 392              $output .=  "*               @user         8\n";
 393          }elseif($d['policy'] == 1){
 394              $output .=  "*               @ALL          1\n";
 395              $output .=  "*               @user         8\n";
 396          }else{
 397              $output .=  "*               @ALL          8\n";
 398          }
 399          $ok = $ok && fileWrite(DOKU_LOCAL.'acl.auth.php', $output);
 400      }
 401  
 402      // enable popularity submission
 403      if($d['pop']){
 404          @touch(DOKU_INC.'data/cache/autosubmit.txt');
 405      }
 406  
 407      // disable auth plugins til needed
 408      $output = <<<EOT
 409  <?php
 410  /*
 411   * Local plugin enable/disable settings
 412   *
 413   * Auto-generated by install script
 414   * Date: $now
 415   */
 416  
 417  \$plugins['authad']    = 0;
 418  \$plugins['authldap']  = 0;
 419  \$plugins['authmysql'] = 0;
 420  \$plugins['authpgsql'] = 0;
 421  
 422  EOT;
 423      $ok = $ok && fileWrite(DOKU_LOCAL.'plugins.local.php', $output);
 424  
 425      return $ok;
 426  }
 427  
 428  /**
 429   * Write the given content to a file
 430   *
 431   * @author  Chris Smith <chris@jalakai.co.uk>
 432   *
 433   * @param string $filename
 434   * @param string $data
 435   * @return bool
 436   */
 437  function fileWrite($filename, $data) {
 438      global $error;
 439      global $lang;
 440  
 441      if (($fp = @fopen($filename, 'wb')) === false) {
 442          $filename = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}/', $filename);
 443          $error[]  = sprintf($lang['i_writeerr'],$filename);
 444          return false;
 445      }
 446  
 447      if (!empty($data)) { fwrite($fp, $data);  }
 448      fclose($fp);
 449      return true;
 450  }
 451  
 452  
 453  /**
 454   * check installation dependent local config files and tests for a known
 455   * unmodified main config file
 456   *
 457   * @author      Chris Smith <chris@jalakai.co.uk>
 458   *
 459   * @return bool
 460   */
 461  function check_configs(){
 462      global $error;
 463      global $lang;
 464  
 465      $ok = true;
 466  
 467      $config_files = array(
 468          'local' => DOKU_LOCAL.'local.php',
 469          'users' => DOKU_LOCAL.'users.auth.php',
 470          'auth'  => DOKU_LOCAL.'acl.auth.php'
 471      );
 472  
 473      // configs shouldn't exist
 474      foreach ($config_files as $file) {
 475          if (file_exists($file) && filesize($file)) {
 476              $file    = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}/', $file);
 477              $error[] = sprintf($lang['i_confexists'],$file);
 478              $ok      = false;
 479          }
 480      }
 481      return $ok;
 482  }
 483  
 484  
 485  /**
 486   * Check other installation dir/file permission requirements
 487   *
 488   * @author      Chris Smith <chris@jalakai.co.uk>
 489   *
 490   * @return bool
 491   */
 492  function check_permissions(){
 493      global $error;
 494      global $lang;
 495  
 496      $dirs = array(
 497          'conf'        => DOKU_LOCAL,
 498          'data'        => DOKU_INC.'data',
 499          'pages'       => DOKU_INC.'data/pages',
 500          'attic'       => DOKU_INC.'data/attic',
 501          'media'       => DOKU_INC.'data/media',
 502          'media_attic' => DOKU_INC.'data/media_attic',
 503          'media_meta'  => DOKU_INC.'data/media_meta',
 504          'meta'        => DOKU_INC.'data/meta',
 505          'cache'       => DOKU_INC.'data/cache',
 506          'locks'       => DOKU_INC.'data/locks',
 507          'index'       => DOKU_INC.'data/index',
 508          'tmp'         => DOKU_INC.'data/tmp'
 509      );
 510  
 511      $ok = true;
 512      foreach($dirs as $dir){
 513          if(!file_exists("$dir/.") || !is_writable($dir)){
 514              $dir     = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}', $dir);
 515              $error[] = sprintf($lang['i_permfail'],$dir);
 516              $ok      = false;
 517          }
 518      }
 519      return $ok;
 520  }
 521  
 522  /**
 523   * Check the availability of functions used in DokuWiki and the PHP version
 524   *
 525   * @author Andreas Gohr <andi@splitbrain.org>
 526   *
 527   * @return bool
 528   */
 529  function check_functions(){
 530      global $error;
 531      global $lang;
 532      $ok = true;
 533  
 534      if(version_compare(phpversion(),'5.6.0','<')){
 535          $error[] = sprintf($lang['i_phpver'],phpversion(),'5.6.0');
 536          $ok = false;
 537      }
 538  
 539      if(ini_get('mbstring.func_overload') != 0){
 540          $error[] = $lang['i_mbfuncoverload'];
 541          $ok = false;
 542      }
 543  
 544      $funcs = explode(' ','addslashes call_user_func chmod copy fgets '.
 545                           'file file_exists fseek flush filesize ftell fopen '.
 546                           'glob header ignore_user_abort ini_get mail mkdir '.
 547                           'ob_start opendir parse_ini_file readfile realpath '.
 548                           'rename rmdir serialize session_start unlink usleep '.
 549                           'preg_replace file_get_contents htmlspecialchars_decode '.
 550                           'spl_autoload_register stream_select fsockopen pack');
 551  
 552      if (!function_exists('mb_substr')) {
 553          $funcs[] = 'utf8_encode';
 554          $funcs[] = 'utf8_decode';
 555      }
 556  
 557      foreach($funcs as $func){
 558          if(!function_exists($func)){
 559              $error[] = sprintf($lang['i_funcna'],$func);
 560              $ok = false;
 561          }
 562      }
 563      return $ok;
 564  }
 565  
 566  /**
 567   * Print language selection
 568   *
 569   * @author Andreas Gohr <andi@splitbrain.org>
 570   */
 571  function langsel(){
 572      global $lang;
 573      global $LC;
 574  
 575      $dir = DOKU_INC.'inc/lang';
 576      $dh  = opendir($dir);
 577      if(!$dh) return;
 578  
 579      $langs = array();
 580      while (($file = readdir($dh)) !== false) {
 581          if(preg_match('/^[\._]/',$file)) continue;
 582          if(is_dir($dir.'/'.$file) && file_exists($dir.'/'.$file.'/lang.php')){
 583              $langs[] = $file;
 584          }
 585      }
 586      closedir($dh);
 587      sort($langs);
 588  
 589      echo '<form action="">';
 590      echo $lang['i_chooselang'];
 591      echo ': <select name="l" onchange="submit()">';
 592      foreach($langs as $l){
 593          $sel = ($l == $LC) ? 'selected="selected"' : '';
 594          echo '<option value="'.$l.'" '.$sel.'>'.$l.'</option>';
 595      }
 596      echo '</select> ';
 597      echo '<button type="submit">'.$lang['btn_update'].'</button>';
 598      echo '</form>';
 599  }
 600  
 601  /**
 602   * Print global error array
 603   *
 604   * @author Andreas Gohr <andi@splitbrain.org>
 605   */
 606  function print_errors(){
 607      global $error;
 608      if(!empty($error)) {
 609          echo '<ul>';
 610          foreach ($error as $err){
 611              echo "<li>$err</li>";
 612          }
 613          echo '</ul>';
 614      }
 615  }