Completed
Push — master ( d5d08c...ea041b )
by Andreas
02:49
created

init.php ➔ isWindows()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Initialize some defaults needed for DokuWiki
4
 */
5
6
/**
7
 * checks it is windows OS
8
 * @return bool
9
 */
10
function isWindows() {
11
    return (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? true : false;
12
}
13
14
/**
15
 * timing Dokuwiki execution
16
 *
17
 * @param integer $start
18
 *
19
 * @return mixed
20
 */
21
function delta_time($start=0) {
22
    return microtime(true)-((float)$start);
23
}
24
define('DOKU_START_TIME', delta_time());
25
26
global $config_cascade;
27
$config_cascade = array();
28
29
// if available load a preload config file
30
$preload = fullpath(dirname(__FILE__)).'/preload.php';
31
if (file_exists($preload)) include($preload);
32
33
// define the include path
34
if(!defined('DOKU_INC')) define('DOKU_INC',fullpath(dirname(__FILE__).'/../').'/');
35
36
// define Plugin dir
37
if(!defined('DOKU_PLUGIN'))  define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
38
39
// define config path (packagers may want to change this to /etc/dokuwiki/)
40
if(!defined('DOKU_CONF')) define('DOKU_CONF',DOKU_INC.'conf/');
41
42
// check for error reporting override or set error reporting to sane values
43
if (!defined('DOKU_E_LEVEL') && file_exists(DOKU_CONF.'report_e_all')) {
44
    define('DOKU_E_LEVEL', E_ALL);
45
}
46
if (!defined('DOKU_E_LEVEL')) {
47
    error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT);
48
} else {
49
    error_reporting(DOKU_E_LEVEL);
50
}
51
52
// init memory caches
53
global $cache_revinfo;
54
       $cache_revinfo = array();
55
global $cache_wikifn;
56
       $cache_wikifn = array();
57
global $cache_cleanid;
58
       $cache_cleanid = array();
59
global $cache_authname;
60
       $cache_authname = array();
61
global $cache_metadata;
62
       $cache_metadata = array();
63
64
// always include 'inc/config_cascade.php'
65
// previously in preload.php set fields of $config_cascade will be merged with the defaults
66
include(DOKU_INC.'inc/config_cascade.php');
67
68
//prepare config array()
69
global $conf;
70
$conf = array();
71
72
// load the global config file(s)
73
foreach (array('default','local','protected') as $config_group) {
74
    if (empty($config_cascade['main'][$config_group])) continue;
75
    foreach ($config_cascade['main'][$config_group] as $config_file) {
76
        if (file_exists($config_file)) {
77
            include($config_file);
78
        }
79
    }
80
}
81
82
//prepare license array()
83
global $license;
84
$license = array();
85
86
// load the license file(s)
87
foreach (array('default','local') as $config_group) {
88
    if (empty($config_cascade['license'][$config_group])) continue;
89
    foreach ($config_cascade['license'][$config_group] as $config_file) {
90
        if(file_exists($config_file)){
91
            include($config_file);
92
        }
93
    }
94
}
95
96
// set timezone (as in pre 5.3.0 days)
97
date_default_timezone_set(@date_default_timezone_get());
98
99
// define baseURL
100
if(!defined('DOKU_REL')) define('DOKU_REL',getBaseURL(false));
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a null|string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
101
if(!defined('DOKU_URL')) define('DOKU_URL',getBaseURL(true));
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a null|string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
102
if(!defined('DOKU_BASE')){
103
    if($conf['canonical']){
104
        define('DOKU_BASE',DOKU_URL);
105
    }else{
106
        define('DOKU_BASE',DOKU_REL);
107
    }
108
}
109
110
// define whitespace
111
if(!defined('DOKU_LF')) define ('DOKU_LF',"\n");
112
if(!defined('DOKU_TAB')) define ('DOKU_TAB',"\t");
113
114
// define cookie and session id, append server port when securecookie is configured FS#1664
115
if (!defined('DOKU_COOKIE')) define('DOKU_COOKIE', 'DW'.md5(DOKU_REL.(($conf['securecookie'])?$_SERVER['SERVER_PORT']:'')));
116
117
118
// define main script
119
if(!defined('DOKU_SCRIPT')) define('DOKU_SCRIPT','doku.php');
120
121
// DEPRECATED, use tpl_basedir() instead
122
if(!defined('DOKU_TPL')) define('DOKU_TPL',
123
        DOKU_BASE.'lib/tpl/'.$conf['template'].'/');
124
125
// DEPRECATED, use tpl_incdir() instead
126
if(!defined('DOKU_TPLINC')) define('DOKU_TPLINC',
127
        DOKU_INC.'lib/tpl/'.$conf['template'].'/');
128
129
// make session rewrites XHTML compliant
130
@ini_set('arg_separator.output', '&amp;');
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
131
132
// make sure global zlib does not interfere FS#1132
133
@ini_set('zlib.output_compression', 'off');
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
134
135
// increase PCRE backtrack limit
136
@ini_set('pcre.backtrack_limit', '20971520');
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
137
138
// enable gzip compression if supported
139
$conf['gzip_output'] &= (strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false);
140
global $ACT;
141
if ($conf['gzip_output'] &&
142
        !defined('DOKU_DISABLE_GZIP_OUTPUT') &&
143
        function_exists('ob_gzhandler') &&
144
        // Disable compression when a (compressed) sitemap might be delivered
145
        // See https://bugs.dokuwiki.org/index.php?do=details&task_id=2576
146
        $ACT != 'sitemap') {
147
    ob_start('ob_gzhandler');
148
}
149
150
// init session
151
if(!headers_sent() && !defined('NOSESSION')) {
152
    if(!defined('DOKU_SESSION_NAME'))     define ('DOKU_SESSION_NAME', "DokuWiki");
153
    if(!defined('DOKU_SESSION_LIFETIME')) define ('DOKU_SESSION_LIFETIME', 0);
154
    if(!defined('DOKU_SESSION_PATH')) {
155
        $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
156
        define ('DOKU_SESSION_PATH', $cookieDir);
157
    }
158
    if(!defined('DOKU_SESSION_DOMAIN'))   define ('DOKU_SESSION_DOMAIN', '');
159
160
    // start the session
161
    init_session();
162
163
    // load left over messages
164
    if(isset($_SESSION[DOKU_COOKIE]['msg'])) {
165
        $MSG = $_SESSION[DOKU_COOKIE]['msg'];
166
        unset($_SESSION[DOKU_COOKIE]['msg']);
167
    }
168
}
169
170
// don't let cookies ever interfere with request vars
171
$_REQUEST = array_merge($_GET,$_POST);
172
173
// we don't want a purge URL to be digged
174
if(isset($_REQUEST['purge']) && !empty($_SERVER['HTTP_REFERER'])) unset($_REQUEST['purge']);
175
176
// precalculate file creation modes
177
init_creationmodes();
178
179
// make real paths and check them
180
init_paths();
181
init_files();
182
183
// setup plugin controller class (can be overwritten in preload.php)
184
$plugin_types = array('auth', 'admin','syntax','action','renderer', 'helper','remote');
185
global $plugin_controller_class, $plugin_controller;
186
if (empty($plugin_controller_class)) $plugin_controller_class = 'Doku_Plugin_Controller';
187
188
// load libraries
189
require_once(DOKU_INC.'vendor/autoload.php');
190
require_once(DOKU_INC.'inc/load.php');
191
192
// disable gzip if not available
193
define('DOKU_HAS_BZIP', function_exists('bzopen'));
194
define('DOKU_HAS_GZIP', function_exists('gzopen'));
195
if($conf['compression'] == 'bz2' && !DOKU_HAS_BZIP) {
196
    $conf['compression'] = 'gz';
197
}
198
if($conf['compression'] == 'gz' && !DOKU_HAS_GZIP) {
199
    $conf['compression'] = 0;
200
}
201
202
// input handle class
203
global $INPUT;
204
$INPUT = new Input();
205
206
// initialize plugin controller
207
$plugin_controller = new $plugin_controller_class();
208
209
// initialize the event handler
210
global $EVENT_HANDLER;
211
$EVENT_HANDLER = new Doku_Event_Handler();
212
213
$local = $conf['lang'];
214
trigger_event('INIT_LANG_LOAD', $local, 'init_lang', true);
215
216
217
// setup authentication system
218
if (!defined('NOSESSION')) {
219
    auth_setup();
220
}
221
222
// setup mail system
223
mail_setup();
224
225
/**
226
 * Initializes the session
227
 *
228
 * Makes sure the passed session cookie is valid, invalid ones are ignored an a new session ID is issued
229
 *
230
 * @link http://stackoverflow.com/a/33024310/172068
231
 * @link http://php.net/manual/en/session.configuration.php#ini.session.sid-length
232
 */
233
function init_session() {
234
    global $conf;
235
    session_name(DOKU_SESSION_NAME);
236
    session_set_cookie_params(DOKU_SESSION_LIFETIME, DOKU_SESSION_PATH, DOKU_SESSION_DOMAIN, ($conf['securecookie'] && is_ssl()), true);
237
238
    // make sure the session cookie contains a valid session ID
239
    if(isset($_COOKIE[DOKU_SESSION_NAME]) && !preg_match('/^[-,a-zA-Z0-9]{22,256}$/', $_COOKIE[DOKU_SESSION_NAME])) {
240
        unset($_COOKIE[DOKU_SESSION_NAME]);
241
    }
242
243
    session_start();
244
}
245
246
247
/**
248
 * Checks paths from config file
249
 */
250
function init_paths(){
251
    global $conf;
252
253
    $paths = array('datadir'   => 'pages',
254
            'olddir'    => 'attic',
255
            'mediadir'  => 'media',
256
            'mediaolddir' => 'media_attic',
257
            'metadir'   => 'meta',
258
            'mediametadir' => 'media_meta',
259
            'cachedir'  => 'cache',
260
            'indexdir'  => 'index',
261
            'lockdir'   => 'locks',
262
            'tmpdir'    => 'tmp');
263
264
    foreach($paths as $c => $p) {
265
        $path = empty($conf[$c]) ? $conf['savedir'].'/'.$p : $conf[$c];
266
        $conf[$c] = init_path($path);
267
        if(empty($conf[$c]))
268
            nice_die("The $c ('$p') at $path is not found, isn't accessible or writable.
269
                You should check your config and permission settings.
270
                Or maybe you want to <a href=\"install.php\">run the
271
                installer</a>?");
272
    }
273
274
    // path to old changelog only needed for upgrading
275
    $conf['changelog_old'] = init_path((isset($conf['changelog']))?($conf['changelog']):($conf['savedir'].'/changes.log'));
276
    if ($conf['changelog_old']=='') { unset($conf['changelog_old']); }
277
    // hardcoded changelog because it is now a cache that lives in meta
278
    $conf['changelog'] = $conf['metadir'].'/_dokuwiki.changes';
279
    $conf['media_changelog'] = $conf['metadir'].'/_media.changes';
280
}
281
282
/**
283
 * Load the language strings
284
 *
285
 * @param string $langCode language code, as passed by event handler
286
 */
287
function init_lang($langCode) {
288
    //prepare language array
289
    global $lang, $config_cascade;
290
    $lang = array();
291
292
    //load the language files
293
    require(DOKU_INC.'inc/lang/en/lang.php');
294
    foreach ($config_cascade['lang']['core'] as $config_file) {
295
        if (file_exists($config_file . 'en/lang.php')) {
296
            include($config_file . 'en/lang.php');
297
        }
298
    }
299
300
    if ($langCode && $langCode != 'en') {
301
        if (file_exists(DOKU_INC."inc/lang/$langCode/lang.php")) {
302
            require(DOKU_INC."inc/lang/$langCode/lang.php");
303
        }
304
        foreach ($config_cascade['lang']['core'] as $config_file) {
305
            if (file_exists($config_file . "$langCode/lang.php")) {
306
                include($config_file . "$langCode/lang.php");
307
            }
308
        }
309
    }
310
}
311
312
/**
313
 * Checks the existence of certain files and creates them if missing.
314
 */
315
function init_files(){
316
    global $conf;
317
318
    $files = array($conf['indexdir'].'/page.idx');
319
320
    foreach($files as $file){
321
        if(!file_exists($file)){
322
            $fh = @fopen($file,'a');
323
            if($fh){
324
                fclose($fh);
325
                if(!empty($conf['fperm'])) chmod($file, $conf['fperm']);
326
            }else{
327
                nice_die("$file is not writable. Check your permissions settings!");
328
            }
329
        }
330
    }
331
}
332
333
/**
334
 * Returns absolute path
335
 *
336
 * This tries the given path first, then checks in DOKU_INC.
337
 * Check for accessibility on directories as well.
338
 *
339
 * @author Andreas Gohr <[email protected]>
340
 *
341
 * @param string $path
342
 *
343
 * @return bool|string
344
 */
345
function init_path($path){
346
    // check existence
347
    $p = fullpath($path);
348
    if(!file_exists($p)){
349
        $p = fullpath(DOKU_INC.$path);
350
        if(!file_exists($p)){
351
            return '';
352
        }
353
    }
354
355
    // check writability
356
    if(!@is_writable($p)){
357
        return '';
358
    }
359
360
    // check accessability (execute bit) for directories
361
    if(@is_dir($p) && !file_exists("$p/.")){
362
        return '';
363
    }
364
365
    return $p;
366
}
367
368
/**
369
 * Sets the internal config values fperm and dperm which, when set,
370
 * will be used to change the permission of a newly created dir or
371
 * file with chmod. Considers the influence of the system's umask
372
 * setting the values only if needed.
373
 */
374
function init_creationmodes(){
375
    global $conf;
376
377
    // Legacy support for old umask/dmask scheme
378
    unset($conf['dmask']);
379
    unset($conf['fmask']);
380
    unset($conf['umask']);
381
    unset($conf['fperm']);
382
    unset($conf['dperm']);
383
384
    // get system umask, fallback to 0 if none available
385
    $umask = @umask();
386
    if(!$umask) $umask = 0000;
387
388
    // check what is set automatically by the system on file creation
389
    // and set the fperm param if it's not what we want
390
    $auto_fmode = 0666 & ~$umask;
391
    if($auto_fmode != $conf['fmode']) $conf['fperm'] = $conf['fmode'];
392
393
    // check what is set automatically by the system on file creation
394
    // and set the dperm param if it's not what we want
395
    $auto_dmode = $conf['dmode'] & ~$umask;
396
    if($auto_dmode != $conf['dmode']) $conf['dperm'] = $conf['dmode'];
397
}
398
399
/**
400
 * Returns the full absolute URL to the directory where
401
 * DokuWiki is installed in (includes a trailing slash)
402
 *
403
 * !! Can not access $_SERVER values through $INPUT
404
 * !! here as this function is called before $INPUT is
405
 * !! initialized.
406
 *
407
 * @author Andreas Gohr <[email protected]>
408
 *
409
 * @param null|string $abs
410
 *
411
 * @return string
412
 */
413
function getBaseURL($abs=null){
414
    global $conf;
415
    //if canonical url enabled always return absolute
416
    if(is_null($abs)) $abs = $conf['canonical'];
417
418
    if(!empty($conf['basedir'])){
419
        $dir = $conf['basedir'];
420
    }elseif(substr($_SERVER['SCRIPT_NAME'],-4) == '.php'){
421
        $dir = dirname($_SERVER['SCRIPT_NAME']);
422
    }elseif(substr($_SERVER['PHP_SELF'],-4) == '.php'){
423
        $dir = dirname($_SERVER['PHP_SELF']);
424
    }elseif($_SERVER['DOCUMENT_ROOT'] && $_SERVER['SCRIPT_FILENAME']){
425
        $dir = preg_replace ('/^'.preg_quote($_SERVER['DOCUMENT_ROOT'],'/').'/','',
426
                $_SERVER['SCRIPT_FILENAME']);
427
        $dir = dirname('/'.$dir);
428
    }else{
429
        $dir = '.'; //probably wrong
430
    }
431
432
    $dir = str_replace('\\','/',$dir);             // bugfix for weird WIN behaviour
433
    $dir = preg_replace('#//+#','/',"/$dir/");     // ensure leading and trailing slashes
434
435
    //handle script in lib/exe dir
436
    $dir = preg_replace('!lib/exe/$!','',$dir);
437
438
    //handle script in lib/plugins dir
439
    $dir = preg_replace('!lib/plugins/.*$!','',$dir);
440
441
    //finish here for relative URLs
442
    if(!$abs) return $dir;
443
444
    //use config option if available, trim any slash from end of baseurl to avoid multiple consecutive slashes in the path
445
    if(!empty($conf['baseurl'])) return rtrim($conf['baseurl'],'/').$dir;
446
447
    //split hostheader into host and port
448
    if(isset($_SERVER['HTTP_HOST'])){
449
        $parsed_host = parse_url('http://'.$_SERVER['HTTP_HOST']);
450
        $host = isset($parsed_host['host']) ? $parsed_host['host'] : null;
451
        $port = isset($parsed_host['port']) ? $parsed_host['port'] : null;
452
    }elseif(isset($_SERVER['SERVER_NAME'])){
453
        $parsed_host = parse_url('http://'.$_SERVER['SERVER_NAME']);
454
        $host = isset($parsed_host['host']) ? $parsed_host['host'] : null;
455
        $port = isset($parsed_host['port']) ? $parsed_host['port'] : null;
456
    }else{
457
        $host = php_uname('n');
458
        $port = '';
459
    }
460
461
    if(is_null($port)){
462
        $port = '';
463
    }
464
465
    if(!is_ssl()){
466
        $proto = 'http://';
467
        if ($port == '80') {
468
            $port = '';
469
        }
470
    }else{
471
        $proto = 'https://';
472
        if ($port == '443') {
473
            $port = '';
474
        }
475
    }
476
477
    if($port !== '') $port = ':'.$port;
478
479
    return $proto.$host.$port.$dir;
480
}
481
482
/**
483
 * Check if accessed via HTTPS
484
 *
485
 * Apache leaves ,$_SERVER['HTTPS'] empty when not available, IIS sets it to 'off'.
486
 * 'false' and 'disabled' are just guessing
487
 *
488
 * @returns bool true when SSL is active
489
 */
490
function is_ssl(){
491
    // check if we are behind a reverse proxy
492
    if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
493
        if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
494
	    return true;
495
	} else {
496
	    return false;
497
	}
498
    }
499
    if (!isset($_SERVER['HTTPS']) ||
500
        preg_match('/^(|off|false|disabled)$/i',$_SERVER['HTTPS'])){
501
        return false;
502
    }else{
503
        return true;
504
    }
505
}
506
507
/**
508
 * print a nice message even if no styles are loaded yet.
509
 *
510
 * @param integer|string $msg
511
 */
512
function nice_die($msg){
513
    echo<<<EOT
514
<!DOCTYPE html>
515
<html>
516
<head><title>DokuWiki Setup Error</title></head>
517
<body style="font-family: Arial, sans-serif">
518
    <div style="width:60%; margin: auto; background-color: #fcc;
519
                border: 1px solid #faa; padding: 0.5em 1em;">
520
        <h1 style="font-size: 120%">DokuWiki Setup Error</h1>
521
        <p>$msg</p>
522
    </div>
523
</body>
524
</html>
525
EOT;
526
    exit(1);
527
}
528
529
/**
530
 * A realpath() replacement
531
 *
532
 * This function behaves similar to PHP's realpath() but does not resolve
533
 * symlinks or accesses upper directories
534
 *
535
 * @author Andreas Gohr <[email protected]>
536
 * @author <richpageau at yahoo dot co dot uk>
537
 * @link   http://php.net/manual/en/function.realpath.php#75992
538
 *
539
 * @param string $path
540
 * @param bool $exists
541
 *
542
 * @return bool|string
543
 */
544
function fullpath($path,$exists=false){
545
    static $run = 0;
546
    $root  = '';
547
    $iswin = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' || @$GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS']);
548
549
    // find the (indestructable) root of the path - keeps windows stuff intact
550
    if($path{0} == '/'){
551
        $root = '/';
552
    }elseif($iswin){
553
        // match drive letter and UNC paths
554
        if(preg_match('!^([a-zA-z]:)(.*)!',$path,$match)){
555
            $root = $match[1].'/';
556
            $path = $match[2];
557
        }else if(preg_match('!^(\\\\\\\\[^\\\\/]+\\\\[^\\\\/]+[\\\\/])(.*)!',$path,$match)){
558
            $root = $match[1];
559
            $path = $match[2];
560
        }
561
    }
562
    $path = str_replace('\\','/',$path);
563
564
    // if the given path wasn't absolute already, prepend the script path and retry
565
    if(!$root){
566
        $base = dirname($_SERVER['SCRIPT_FILENAME']);
567
        $path = $base.'/'.$path;
568
        if($run == 0){ // avoid endless recursion when base isn't absolute for some reason
569
            $run++;
570
            return fullpath($path,$exists);
571
        }
572
    }
573
    $run = 0;
574
575
    // canonicalize
576
    $path=explode('/', $path);
577
    $newpath=array();
578
    foreach($path as $p) {
579
        if ($p === '' || $p === '.') continue;
580
        if ($p==='..') {
581
            array_pop($newpath);
582
            continue;
583
        }
584
        array_push($newpath, $p);
585
    }
586
    $finalpath = $root.implode('/', $newpath);
587
588
    // check for existence when needed (except when unit testing)
589
    if($exists && !defined('DOKU_UNITTEST') && !file_exists($finalpath)) {
590
        return false;
591
    }
592
    return $finalpath;
593
}
594
595