xref: /dokuwiki/inc/init.php (revision b80bedd6525e59ec7dd21aa8156d2575944f101e)
1<?php
2/**
3 * Initialize some defaults needed for DokuWiki
4 */
5
6  // start timing Dokuwiki execution
7  function delta_time($start=0) {
8    list($usec, $sec) = explode(" ", microtime());
9    return ((float)$usec+(float)$sec)-((float)$start);
10  }
11  define('DOKU_START_TIME', delta_time());
12
13  // define the include path
14  if(!defined('DOKU_INC')) define('DOKU_INC',fullpath(dirname(__FILE__).'/../').'/');
15
16  // trigger DOKUWIKI_INIT event to allow action plugins to overwrite constants
17  // load events.php, external scripts can just include inc/init.php
18  require_once(DOKU_INC.'inc/events.php');
19  trigger_event('DOKUWIKI_INIT', $tmp=array());
20
21  // define config path (packagers may want to change this to /etc/dokuwiki/)
22  if(!defined('DOKU_CONF')) define('DOKU_CONF',DOKU_INC.'conf/');
23
24  // check for error reporting override or set error reporting to sane values
25  if (!defined('DOKU_E_LEVEL') && @file_exists(DOKU_CONF.'report_e_all')) {
26    define('DOKU_E_LEVEL', E_ALL);
27  }
28  if (!defined('DOKU_E_LEVEL')) { error_reporting(E_ALL ^ E_NOTICE); }
29  else { error_reporting(DOKU_E_LEVEL); }
30
31  // init memory caches
32  global $cache_revinfo;  $cache_revinfo = array();
33  global $cache_wikifn;   $cache_wikifn = array();
34  global $cache_cleanid;  $cache_cleanid = array();
35  global $cache_authname; $cache_authname = array();
36  global $cache_metadata; $cache_metadata = array();
37
38  //prepare config array()
39  global $conf;
40  if (!defined('DOKU_UNITTEST')) {
41    $conf = array();
42
43    // load the config file(s)
44    require_once(DOKU_CONF.'dokuwiki.php');
45    if(@file_exists(DOKU_CONF.'local.php')){
46      require_once(DOKU_CONF.'local.php');
47    }
48  }
49
50  //prepare language array
51  global $lang;
52  $lang = array();
53
54  //load the language files
55  require_once(DOKU_INC.'inc/lang/en/lang.php');
56  if ( $conf['lang'] && $conf['lang'] != 'en' ) {
57    require_once(DOKU_INC.'inc/lang/'.$conf['lang'].'/lang.php');
58  }
59
60  // define baseURL
61  if(!defined('DOKU_REL')) define('DOKU_REL',getBaseURL(false));
62  if(!defined('DOKU_URL')) define('DOKU_URL',getBaseURL(true));
63  if(!defined('DOKU_BASE')){
64    if($conf['canonical']){
65      define('DOKU_BASE',DOKU_URL);
66    }else{
67      define('DOKU_BASE',DOKU_REL);
68    }
69  }
70
71  // define whitespace
72  if(!defined('DOKU_LF')) define ('DOKU_LF',"\n");
73  if(!defined('DOKU_TAB')) define ('DOKU_TAB',"\t");
74
75  // define cookie and session id
76  if (!defined('DOKU_COOKIE')) define('DOKU_COOKIE', 'DW'.md5(DOKU_REL));
77
78  // define Plugin dir
79  if(!defined('DOKU_PLUGIN'))  define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
80
81  // define main script
82  if(!defined('DOKU_SCRIPT')) define('DOKU_SCRIPT','doku.php');
83
84  // define Template baseURL
85  if(!defined('DOKU_TPL')) define('DOKU_TPL',
86                                  DOKU_BASE.'lib/tpl/'.$conf['template'].'/');
87
88  // define real Template directory
89  if(!defined('DOKU_TPLINC')) define('DOKU_TPLINC',
90                                  DOKU_INC.'lib/tpl/'.$conf['template'].'/');
91
92  // make session rewrites XHTML compliant
93  @ini_set('arg_separator.output', '&amp;');
94
95  // make sure global zlib does not interfere FS#1132
96  @ini_set('zlib.output_compression', 'off');
97
98  // increase PCRE backtrack limit
99  @ini_set('pcre.backtrack_limit', '20971520');
100
101  // enable gzip compression
102  if ($conf['gzip_output'] &&
103      !defined('DOKU_DISABLE_GZIP_OUTPUT') &&
104      function_exists('ob_gzhandler') &&
105      preg_match('/gzip|deflate/', $_SERVER['HTTP_ACCEPT_ENCODING'])) {
106    ob_start('ob_gzhandler');
107  }
108
109  // init session
110  if (!headers_sent() && !defined('NOSESSION')){
111    session_name("DokuWiki");
112    session_set_cookie_params(0, DOKU_REL);
113    session_start();
114  }
115
116  // kill magic quotes
117  if (get_magic_quotes_gpc() && !defined('MAGIC_QUOTES_STRIPPED')) {
118    if (!empty($_GET))    remove_magic_quotes($_GET);
119    if (!empty($_POST))   remove_magic_quotes($_POST);
120    if (!empty($_COOKIE)) remove_magic_quotes($_COOKIE);
121    if (!empty($_REQUEST)) remove_magic_quotes($_REQUEST);
122    @ini_set('magic_quotes_gpc', 0);
123    define('MAGIC_QUOTES_STRIPPED',1);
124  }
125  @set_magic_quotes_runtime(0);
126  @ini_set('magic_quotes_sybase',0);
127
128  // don't let cookies ever interfere with request vars
129  $_REQUEST = array_merge($_GET,$_POST);
130
131  // disable gzip if not available
132  if($conf['compression'] == 'bz2' && !function_exists('bzopen')){
133    $conf['compression'] = 'gz';
134  }
135  if($conf['compression'] == 'gz' && !function_exists('gzopen')){
136    $conf['compression'] = 0;
137  }
138
139  // fix dateformat for upgraders
140  if(strpos($conf['dformat'],'%') === false){
141    $conf['dformat'] = '%Y/%m/%d %H:%M';
142  }
143
144  // precalculate file creation modes
145  init_creationmodes();
146
147  // make real paths and check them
148  init_paths();
149  init_files();
150
151  // automatic upgrade to script versions of certain files
152  scriptify(DOKU_CONF.'users.auth');
153  scriptify(DOKU_CONF.'acl.auth');
154
155
156/**
157 * Checks paths from config file
158 */
159function init_paths(){
160  global $conf;
161
162  $paths = array('datadir'   => 'pages',
163                 'olddir'    => 'attic',
164                 'mediadir'  => 'media',
165                 'metadir'   => 'meta',
166                 'cachedir'  => 'cache',
167                 'indexdir'  => 'index',
168                 'lockdir'   => 'locks',
169                 'tmpdir'    => 'tmp');
170
171  foreach($paths as $c => $p){
172    if(empty($conf[$c]))  $conf[$c] = $conf['savedir'].'/'.$p;
173    $conf[$c]             = init_path($conf[$c]);
174    if(empty($conf[$c]))  nice_die("The $c ('$p') does not exist, isn't accessible or writable.
175                               You should check your config and permission settings.
176                               Or maybe you want to <a href=\"install.php\">run the
177                               installer</a>?");
178  }
179
180  // path to old changelog only needed for upgrading
181  $conf['changelog_old'] = init_path((isset($conf['changelog']))?($conf['changelog']):($conf['savedir'].'/changes.log'));
182  if ($conf['changelog_old']=='') { unset($conf['changelog_old']); }
183  // hardcoded changelog because it is now a cache that lives in meta
184  $conf['changelog'] = $conf['metadir'].'/_dokuwiki.changes';
185}
186
187/**
188 * Checks the existance of certain files and creates them if missing.
189 */
190function init_files(){
191  global $conf;
192
193  $files = array( $conf['indexdir'].'/page.idx');
194
195  foreach($files as $file){
196    if(!@file_exists($file)){
197      $fh = @fopen($file,'a');
198      if($fh){
199        fclose($fh);
200        if($conf['fperm']) chmod($file, $conf['fperm']);
201      }else{
202        nice_die("$file is not writable. Check your permissions settings!");
203      }
204    }
205  }
206}
207
208/**
209 * Returns absolute path
210 *
211 * This tries the given path first, then checks in DOKU_INC.
212 * Check for accessability on directories as well.
213 *
214 * @author Andreas Gohr <andi@splitbrain.org>
215 */
216function init_path($path){
217  // check existance
218  $p = fullpath($path);
219  if(!@file_exists($p)){
220    $p = fullpath(DOKU_INC.$path);
221    if(!@file_exists($p)){
222      return '';
223    }
224  }
225
226  // check writability
227  if(!@is_writable($p)){
228    return '';
229  }
230
231  // check accessability (execute bit) for directories
232  if(@is_dir($p) && !@file_exists("$p/.")){
233    return '';
234  }
235
236  return $p;
237}
238
239/**
240 * Sets the internal config values fperm and dperm which, when set,
241 * will be used to change the permission of a newly created dir or
242 * file with chmod. Considers the influence of the system's umask
243 * setting the values only if needed.
244 */
245function init_creationmodes(){
246  global $conf;
247
248  // Legacy support for old umask/dmask scheme
249  unset($conf['dmask']);
250  unset($conf['fmask']);
251  unset($conf['umask']);
252  unset($conf['fperm']);
253  unset($conf['dperm']);
254
255  // get system umask, fallback to 0 if none available
256  $umask = @umask();
257  if(!$umask) $umask = 0000;
258
259  // check what is set automatically by the system on file creation
260  // and set the fperm param if it's not what we want
261  $auto_fmode = 0666 & ~$umask;
262  if($auto_fmode != $conf['fmode']) $conf['fperm'] = $conf['fmode'];
263
264  // check what is set automatically by the system on file creation
265  // and set the dperm param if it's not what we want
266  $auto_dmode = $conf['dmode'] & ~$umask;
267  if($auto_dmode != $conf['dmode']) $conf['dperm'] = $conf['dmode'];
268}
269
270/**
271 * remove magic quotes recursivly
272 *
273 * @author Andreas Gohr <andi@splitbrain.org>
274 */
275function remove_magic_quotes(&$array) {
276  foreach (array_keys($array) as $key) {
277      // handle magic quotes in keynames (breaks order)
278      $sk = stripslashes($key);
279      if($sk != $key){
280          $array[$sk] = $array[$key];
281          unset($array[$key]);
282          $key = $sk;
283      }
284
285      // do recursion if needed
286      if (is_array($array[$key])) {
287          remove_magic_quotes($array[$key]);
288      }else {
289          $array[$key] = stripslashes($array[$key]);
290      }
291  }
292}
293
294/**
295 * Returns the full absolute URL to the directory where
296 * DokuWiki is installed in (includes a trailing slash)
297 *
298 * @author Andreas Gohr <andi@splitbrain.org>
299 */
300function getBaseURL($abs=null){
301  global $conf;
302  //if canonical url enabled always return absolute
303  if(is_null($abs)) $abs = $conf['canonical'];
304
305  if($conf['basedir']){
306    $dir = $conf['basedir'];
307  }elseif(substr($_SERVER['SCRIPT_NAME'],-4) == '.php'){
308    $dir = dirname($_SERVER['SCRIPT_NAME']);
309  }elseif(substr($_SERVER['PHP_SELF'],-4) == '.php'){
310    $dir = dirname($_SERVER['PHP_SELF']);
311  }elseif($_SERVER['DOCUMENT_ROOT'] && $_SERVER['SCRIPT_FILENAME']){
312    $dir = preg_replace ('/^'.preg_quote($_SERVER['DOCUMENT_ROOT'],'/').'/','',
313                         $_SERVER['SCRIPT_FILENAME']);
314    $dir = dirname('/'.$dir);
315  }else{
316    $dir = '.'; //probably wrong
317  }
318
319  $dir = str_replace('\\','/',$dir);             // bugfix for weird WIN behaviour
320  $dir = preg_replace('#//+#','/',"/$dir/");     // ensure leading and trailing slashes
321
322  //handle script in lib/exe dir
323  $dir = preg_replace('!lib/exe/$!','',$dir);
324
325  //handle script in lib/plugins dir
326  $dir = preg_replace('!lib/plugins/.*$!','',$dir);
327
328  //finish here for relative URLs
329  if(!$abs) return $dir;
330
331  //use config option if available, trim any slash from end of baseurl to avoid multiple consecutive slashes in the path
332  if($conf['baseurl']) return rtrim($conf['baseurl'],'/').$dir;
333
334  //split hostheader into host and port
335  list($host,$port) = explode(':',$_SERVER['HTTP_HOST']);
336  if(!$port)  $port = $_SERVER['SERVER_PORT'];
337  if(!$port)  $port = 80;
338
339  // see if HTTPS is enabled - apache leaves this empty when not available,
340  // IIS sets it to 'off', 'false' and 'disabled' are just guessing
341  if (preg_match('/^(|off|false|disabled)$/i',$_SERVER['HTTPS'])){
342    $proto = 'http://';
343    if ($port == '80') {
344      $port='';
345    }
346  }else{
347    $proto = 'https://';
348    if ($port == '443') {
349      $port='';
350    }
351  }
352
353  if($port) $port = ':'.$port;
354
355  return $proto.$host.$port.$dir;
356}
357
358/**
359 * Append a PHP extension to a given file and adds an exit call
360 *
361 * This is used to migrate some old configfiles. An added PHP extension
362 * ensures the contents are not shown to webusers even if .htaccess files
363 * do not work
364 *
365 * @author Jan Decaluwe <jan@jandecaluwe.com>
366 */
367function scriptify($file) {
368  // checks
369  if (!is_readable($file)) {
370    return;
371  }
372  $fn = $file.'.php';
373  if (@file_exists($fn)) {
374    return;
375  }
376  $fh = fopen($fn, 'w');
377  if (!$fh) {
378    nice_die($fn.' is not writable. Check your permission settings!');
379  }
380  // write php exit hack first
381  fwrite($fh, "# $fn\n");
382  fwrite($fh, '# <?php exit()?>'."\n");
383  fwrite($fh, "# Don't modify the lines above\n");
384  fwrite($fh, "#\n");
385  // copy existing lines
386  $lines = file($file);
387  foreach ($lines as $line){
388    fwrite($fh, $line);
389  }
390  fclose($fh);
391  //try to rename the old file
392  io_rename($file,"$file.old");
393}
394
395/**
396 * print a nice message even if no styles are loaded yet.
397 */
398function nice_die($msg){
399  echo<<<EOT
400  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
401   "http://www.w3.org/TR/html4/loose.dtd">
402  <html>
403    <head><title>DokuWiki Setup Error</title></head>
404    <body style="font-family: Arial, sans-serif">
405      <div style="width:60%; margin: auto; background-color: #fcc;
406                  border: 1px solid #faa; padding: 0.5em 1em;">
407      <h1 style="font-size: 120%">DokuWiki Setup Error</h1>
408      <p>$msg</p>
409      </div>
410    </body>
411  </html>
412EOT;
413  exit;
414}
415
416
417/**
418 * A realpath() replacement
419 *
420 * This function behaves similar to PHP's realpath() but does not resolve
421 * symlinks or accesses upper directories
422 *
423 * @author <richpageau at yahoo dot co dot uk>
424 * @link   http://de3.php.net/manual/en/function.realpath.php#75992
425 */
426function fullpath($path){
427    $iswin = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
428    $isunc = 0===strpos($path,'\\\\');
429    if($iswin) $path = str_replace('\\','/',$path); // windows compatibility
430
431    // check if path begins with "/" or "c:" ie. is absolute
432    // if it isnt concat with script path
433    if (!$isunc &&
434        ((!$iswin && $path{0} !== '/') ||
435         ($iswin && $path{1} !== ':'))) {
436        $base=dirname($_SERVER['SCRIPT_FILENAME']);
437        $path=$base."/".$path;
438    }
439
440    // canonicalize
441    $path=explode('/', $path);
442    $newpath=array();
443    foreach($path as $p) {
444        if ($p === '' || $p === '.') continue;
445           if ($p==='..') {
446              array_pop($newpath);
447              continue;
448        }
449        array_push($newpath, $p);
450    }
451    $finalpath = implode('/', $newpath);
452    if($isunc) $finalpath = '//'.$finalpath;
453    if(!$iswin) $finalpath = '/'.$finalpath;
454
455    // check then return valid path or filename
456    if (file_exists($finalpath)) {
457        return ($finalpath);
458    }
459    else return false;
460}
461
462
463
464//Setup VIM: ex: et ts=2 enc=utf-8 :
465