Issues (2811)

public/htdocs/install/inc.php (2 issues)

1
<?php
2
3
/* Copyright (C) 2004       Rodolphe Quiedeville        <[email protected]>
4
 * Copyright (C) 2004       Benoit Mortier              <[email protected]>
5
 * Copyright (C) 2004       Sebastien DiCintio          <[email protected]>
6
 * Copyright (C) 2007-2012  Laurent Destailleur         <[email protected]>
7
 * Copyright (C) 2012       Marcos García               <[email protected]>
8
 * Copyright (C) 2016       Raphaël Doursenaud          <[email protected]>
9
 * Copyright (C) 2021       Charlene Benke      	    <[email protected]>
10
 * Copyright (C) 2023       Alexandre Janniaux          <[email protected]>
11
 * Copyright (C) 2024		MDW							<[email protected]>
12
 * Copyright (C) 2024       Rafael San José             <[email protected]>
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 3 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
26
 */
27
28
use Dolibarr\Code\Core\Classes\Conf;
29
use Dolibarr\Code\Core\Classes\Translate;
30
31
/**
32
 *    \file       htdocs/install/inc.php
33
 *    \ingroup    core
34
 *    \brief      File that define environment for support pages
35
 */
36
37
// Just to define version DOL_VERSION
38
if (!defined('DOL_INC_FOR_VERSION_ERROR')) {
39
    define('DOL_INC_FOR_VERSION_ERROR', '1');
40
}
41
require_once constant('DOL_DOCUMENT_ROOT') . '/filefunc.inc.php';
42
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/functions.lib.php';
43
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/admin.lib.php';
44
require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/files.lib.php';
45
46
$conf = new Conf();
47
48
// Force $_REQUEST["logtohtml"]
49
$_REQUEST["logtohtml"] = 1;
50
51
// Correction PHP_SELF (ex pour apache via caudium) car PHP_SELF doit valoir URL relative
52
// et non path absolu.
53
if (isset($_SERVER["DOCUMENT_URI"]) && $_SERVER["DOCUMENT_URI"]) {
54
    $_SERVER["PHP_SELF"] = $_SERVER["DOCUMENT_URI"];
55
}
56
57
58
$includeconferror = '';
59
60
61
// Define vars
62
$conffiletoshowshort = "conf.php";
63
// Define localization of conf file
64
$conffile = constant('DOL_DOCUMENT_ROOT') . '/conf/conf.php';
65
$conffiletoshow = "conf/conf.php";
66
// For debian/redhat like systems
67
//$conffile = "/etc/dolibarr/conf.php";
68
//$conffiletoshow = "/etc/dolibarr/conf.php";
69
70
$short_options = "c:h";
71
$long_options = array(
72
    "config:",
73
    "help",
74
);
75
76
/**
77
 * Print the usage when executing scripts from install/.
78
 *
79
 * Print the help text exposing the available options when executing
80
 * update or install script (ie. from htdocs/install/) from CLI with
81
 * the `php` executable. This function does not `exit` the program and
82
 * the caller should then call `exit` themselves since they should
83
 * determine whether it was an error or not.
84
 *
85
 * @param string $program the script that was originally run
86
 * @param string $header the message to signal to the user
87
 * @return void
88
 */
89
function usage($program, $header)
90
{
91
    echo $header . "\n";
92
    echo "  php " . $program . " [options] [script options]\n";
93
    echo "\n";
94
    echo "Script syntax when using step2.php:\n";
95
    echo "  php " . $program . " [options] [action] [selectlang]\n";
96
    echo "\n";
97
    echo "  action:\n";
98
    echo "      Specify the action to execute for the file among the following ones.\n";
99
    echo "       - set: Create tables, keys, functions and data for the instance.\n";
100
    echo "\n";
101
    echo "  selectlang:\n";
102
    echo "      Setup the default lang to use, default to 'auto'.\n";
103
    echo "\n";
104
    echo "Script syntax when using upgrade.php:\n";
105
    echo "  php " . $program . " [options] previous_version new_version [script options]\n";
106
    echo "\n";
107
    echo "  dirmodule:\n";
108
    echo "      Specify dirmodule to provide a path for an external module\n";
109
    echo "      so the migration is done using a script from a module.\n";
110
    echo "\n";
111
    echo "  ignoredbversion:\n";
112
    echo "      Allow to run migration even if database version does\n";
113
    echo "      not match start version of migration.\n";
114
    echo "\n";
115
    echo "Script syntax when using upgrade2.php:\n";
116
    echo "  php " . $program . " [options] previous_version new_version [module list]\n";
117
    echo "\n";
118
    echo "  MAIN_MODULE_NAME1,MAIN_MODULE_NAME2:\n";
119
    echo "      Specify a list of module-name to enable, in upper case, with MAIN_MODULE_ prefix, joined by comma.\n";
120
    echo "\n";
121
    echo "Options:\n";
122
    echo "  -c, --config <filename>:\n";
123
    echo "      Provide a different conf.php file to use.\n";
124
    echo "\n";
125
    echo "  -h, --help:\n";
126
    echo "      Display this help message.\n";
127
}
128
129
if (php_sapi_name() === "cli" && (float)PHP_VERSION > 7.0) {
130
    $rest_index = 0;
131
    $opts = getopt($short_options, $long_options, $rest_index);
132
133
    foreach ($opts as $opt => $arg) {
134
        switch ($opt) {
135
            case 'c':
136
            case 'config':
137
                $conffile = $arg;
138
                $conffiletoshow = $arg;
139
                break;
140
            case 'h':
141
            case 'help':
142
                usage($argv[0], "Usage:");
143
                exit(0);
144
        }
145
    }
146
147
    // Parse the arguments to find the options.
148
    $args_options = array_filter(
149
        array_slice($argv, 0, $rest_index),
150
        /**
151
         * @param string $arg
152
         * @return bool
153
         */
154
        static function ($arg) {
155
            return strlen($arg) >= 2 && $arg[0] == '-';
156
        }
157
    );
158
    $parsed_options = array_map(
159
    /**
160
     * Previx option with '-' for single characters and -- for more than single characters
161
     * @param string $arg
162
     * @return string
163
     */
164
        static function ($arg) {
165
            if (strlen($arg) > 1) {
166
                return "--" . $arg;
167
            }
168
            return "-" . $arg;
169
        },
170
        array_keys($opts)
171
    );
172
173
    // Find options (dash-prefixed) that were not parsed.
174
    $unknown_options = array_diff($args_options, $parsed_options);
175
176
    // In the following test, only dash-prefixed arguments will trigger an
177
    // error, given that scripts options can allow a variable number of
178
    // additional non-prefixed argument and we mostly want to check for
179
    // typo right now.
180
    if (count($unknown_options) > 0) {
181
        echo "Unknown option: " . array_values($unknown_options)[0] . "\n";
182
        usage($argv[0], "Usage:");
183
        exit(1);
184
    }
185
186
    // Tricky argument list hack, should be removed someday.
187
    // Reset argv to remove the argument that were parsed. This is needed
188
    // currently because some install code, like in upgrade.php, are using
189
    // $argv[] directly with fixed index to fetch some arguments.
190
    $argv = array_merge(array($argv[0]), array_slice($argv, $rest_index));
191
    $argc = count($argv);
192
}
193
194
// Load conf file if it is already defined
195
if (!defined('DONOTLOADCONF') && file_exists($conffile) && filesize($conffile) > 8) { // Test on filesize is to ensure that conf file is more that an empty template with just <?php in first line
196
    $result = include_once $conffile; // Load conf file
197
    if ($result) {
198
        if (empty($dolibarr_main_db_type)) {
199
            $dolibarr_main_db_type = 'mysqli'; // For backward compatibility
200
        }
201
202
        //Mysql driver support has been removed in favor of mysqli
203
        if ($dolibarr_main_db_type == 'mysql') {
204
            $dolibarr_main_db_type = 'mysqli';
205
        }
206
207
        if (!isset($dolibarr_main_db_port) && ($dolibarr_main_db_type == 'mysqli')) {
208
            $dolibarr_main_db_port = '3306'; // For backward compatibility
209
        }
210
211
        // Clean parameters
212
        $dolibarr_main_data_root = isset($dolibarr_main_data_root) ? trim($dolibarr_main_data_root) : DOL_DOCUMENT_ROOT . '/../documents';
213
        $dolibarr_main_url_root = isset($dolibarr_main_url_root) ? trim($dolibarr_main_url_root) : '';
214
        $dolibarr_main_url_root_alt = isset($dolibarr_main_url_root_alt) ? trim($dolibarr_main_url_root_alt) : '';
215
        $dolibarr_main_document_root = isset($dolibarr_main_document_root) ? trim($dolibarr_main_document_root) : '';
216
        $dolibarr_main_document_root_alt = isset($dolibarr_main_document_root_alt) ? trim($dolibarr_main_document_root_alt) : '';
217
218
        // Remove last / or \ on directories or url value
219
        if (!empty($dolibarr_main_document_root) && !preg_match('/^[\\/]+$/', $dolibarr_main_document_root)) {
220
            $dolibarr_main_document_root = preg_replace('/[\\/]+$/', '', $dolibarr_main_document_root);
221
        }
222
        if (!empty($dolibarr_main_url_root) && !preg_match('/^[\\/]+$/', $dolibarr_main_url_root)) {
223
            $dolibarr_main_url_root = preg_replace('/[\\/]+$/', '', $dolibarr_main_url_root);
224
        }
225
        if (!empty($dolibarr_main_data_root) && !preg_match('/^[\\/]+$/', $dolibarr_main_data_root)) {
226
            $dolibarr_main_data_root = preg_replace('/[\\/]+$/', '', $dolibarr_main_data_root);
227
        }
228
        if (!empty($dolibarr_main_document_root_alt) && !preg_match('/^[\\/]+$/', $dolibarr_main_document_root_alt)) {
229
            $dolibarr_main_document_root_alt = preg_replace('/[\\/]+$/', '', $dolibarr_main_document_root_alt);
230
        }
231
        if (!empty($dolibarr_main_url_root_alt) && !preg_match('/^[\\/]+$/', $dolibarr_main_url_root_alt)) {
232
            $dolibarr_main_url_root_alt = preg_replace('/[\\/]+$/', '', $dolibarr_main_url_root_alt);
233
        }
234
235
        // Create conf object
236
        if (!empty($dolibarr_main_document_root)) {
237
            $result = conf($dolibarr_main_document_root);
238
        }
239
        // Load database driver
240
        if ($result) {
241
            if (!empty($dolibarr_main_document_root) && !empty($dolibarr_main_db_type)) {
242
                $result = include_once $dolibarr_main_document_root . "/core/db/" . $dolibarr_main_db_type . '.class.php';
243
                if (!$result) {
244
                    $includeconferror = 'ErrorBadValueForDolibarrMainDBType';
245
                }
246
            }
247
        } else {
248
            $includeconferror = 'ErrorBadValueForDolibarrMainDocumentRoot';
249
        }
250
    } else {
251
        $includeconferror = 'ErrorBadFormatForConfFile';
252
    }
253
}
254
255
$conf->global->MAIN_ENABLE_LOG_TO_HTML = 1;
256
257
// Define prefix
258
if (!isset($dolibarr_main_db_prefix) || !$dolibarr_main_db_prefix) {
259
    $dolibarr_main_db_prefix = constant('DEFAULT_DB_PREFIX');
260
}
261
define('MAIN_DB_PREFIX', (isset($dolibarr_main_db_prefix) ? $dolibarr_main_db_prefix : ''));
262
263
define('DOL_CLASS_PATH', 'class/'); // Filesystem path to class dir
264
define('DOL_DATA_ROOT', (isset($dolibarr_main_data_root) ? $dolibarr_main_data_root : DOL_DOCUMENT_ROOT . '/../documents'));
265
define('DOL_MAIN_URL_ROOT', (isset($dolibarr_main_url_root) ? $dolibarr_main_url_root : '')); // URL relative root
266
267
if (empty($conf->file->character_set_client)) {
268
    $conf->file->character_set_client = "utf-8";
269
}
270
if (empty($conf->db->character_set)) {
271
    $conf->db->character_set = 'utf8';
272
}
273
if (empty($conf->db->dolibarr_main_db_collation)) {
274
    $conf->db->dolibarr_main_db_collation = 'utf8_unicode_ci';
275
}
276
if (empty($conf->db->dolibarr_main_db_encryption)) {
277
    $conf->db->dolibarr_main_db_encryption = 0;
278
}
279
if (empty($conf->db->dolibarr_main_db_cryptkey)) {
280
    $conf->db->dolibarr_main_db_cryptkey = '';
281
}
282
if (empty($conf->db->user)) {
283
    $conf->db->user = '';
284
}
285
286
// Define array of document root directories
287
$conf->file->dol_document_root = array(DOL_DOCUMENT_ROOT);
288
if (!empty($dolibarr_main_document_root_alt)) {
289
    // dolibarr_main_document_root_alt contains several directories
290
    $values = preg_split('/[;,]/', $dolibarr_main_document_root_alt);
291
    foreach ($values as $value) {
292
        $conf->file->dol_document_root[] = $value;
293
    }
294
}
295
296
297
// Check install.lock (for both install and upgrade)
298
299
$lockfile = DOL_DATA_ROOT . '/install.lock';    // To lock all /install pages
300
$lockfile2 = DOL_DOCUMENT_ROOT . '/install.lock';    // To lock all /install pages (recommended)
301
$upgradeunlockfile = DOL_DATA_ROOT . '/upgrade.unlock';    // To unlock upgrade process
302
$upgradeunlockfile2 = DOL_DOCUMENT_ROOT . '/upgrade.unlock';    // To unlock upgrade process
303
if (constant('DOL_DATA_ROOT') === null) {
304
    // We don't have a configuration file yet
305
    // Try to detect any lockfile in the default documents path
306
    $lockfile = '../../documents/install.lock';
307
    $upgradeunlockfile = '../../documents/upgrade.unlock';
308
}
309
$islocked = false;
310
if (@file_exists($lockfile) || @file_exists($lockfile2)) {
311
    if (!defined('ALLOWED_IF_UPGRADE_UNLOCK_FOUND') || (!@file_exists($upgradeunlockfile) && !@file_exists($upgradeunlockfile2))) {
312
        // If this is a dangerous install page (ALLOWED_IF_UPGRADE_UNLOCK_FOUND not defined) or
313
        // if there is no upgrade unlock files, we lock the pages.
314
        $islocked = true;
315
    }
316
}
317
if ($islocked) {    // Pages are locked
318
    if (!isset($langs) || !is_object($langs)) {
319
        $langs = new Translate('..', $conf);
320
        $langs->setDefaultLang('auto');
321
    }
322
    $langs->load("install");
323
324
    header("X-Content-Type-Options: nosniff");
325
    header("X-Frame-Options: SAMEORIGIN"); // Frames allowed only if on same domain (stop some XSS attacks)
326
327
    if (GETPOST('action') != 'upgrade') {
328
        print $langs->trans("YouTryInstallDisabledByFileLock") . '<br>';
329
    } else {
330
        print $langs->trans("YouTryUpgradeDisabledByMissingFileUnLock") . '<br>';
331
    }
332
    if (!empty($dolibarr_main_url_root)) {
333
        if (GETPOST('action') != 'upgrade' && (!file_exists($conffile) || !isset($dolibarr_main_url_root))) {
334
            print $langs->trans("ClickOnLinkOrRemoveManualy") . '<br>';
335
        } else {
336
            print $langs->trans("ClickOnLinkOrCreateUnlockFileManualy") . '<br>';
337
        }
338
        print '<a href="' . $dolibarr_main_url_root . '/admin/index.php?mainmenu=home&leftmenu=setup' . (GETPOSTISSET("login") ? '&username=' . urlencode(GETPOST("login")) : '') . '">';
339
        print $langs->trans("ClickHereToGoToApp");
340
        print '</a>';
341
    } else {
342
        print 'If you always reach this page, you must remove the install.lock file manually.<br>';
343
    }
344
    exit;
345
}
346
347
348
// Force usage of log file for install and upgrades
349
$conf->modules['syslog'] = 'syslog';
350
$conf->global->SYSLOG_LEVEL = constant('LOG_DEBUG');
351
if (!defined('SYSLOG_HANDLERS')) {
352
    define('SYSLOG_HANDLERS', '["mod_syslog_file"]');
353
}
354
if (!defined('SYSLOG_FILE')) {    // To avoid warning on systems with constant already defined
355
    if (@is_writable('/tmp')) {
356
        define('SYSLOG_FILE', '/tmp/dolibarr_install.log');
357
    } elseif (!empty($_ENV["TMP"]) && @is_writable($_ENV["TMP"])) {
358
        define('SYSLOG_FILE', $_ENV["TMP"] . '/dolibarr_install.log');
359
    } elseif (!empty($_ENV["TEMP"]) && @is_writable($_ENV["TEMP"])) {
360
        define('SYSLOG_FILE', $_ENV["TEMP"] . '/dolibarr_install.log');
361
    } elseif (@is_writable('../../../../') && @file_exists('../../../../startdoliwamp.bat')) {
362
        define('SYSLOG_FILE', '../../../../dolibarr_install.log'); // For DoliWamp
363
    } elseif (@is_writable('../../')) {
364
        define('SYSLOG_FILE', '../../dolibarr_install.log'); // For others
365
    }
366
    //print 'SYSLOG_FILE='.SYSLOG_FILE;exit;
367
}
368
if (defined('SYSLOG_FILE')) {
369
    $conf->global->SYSLOG_FILE = constant('SYSLOG_FILE');
370
}
371
if (!defined('SYSLOG_FILE_NO_ERROR')) {
372
    define('SYSLOG_FILE_NO_ERROR', 1);
373
}
374
// We init log handler for install
375
$handlers = array('mod_syslog_file');
376
foreach ($handlers as $handler) {
377
    $file = DOL_DOCUMENT_ROOT . '/core/modules/syslog/' . $handler . '.php';
378
    if (!file_exists($file)) {
379
        throw new Exception('Missing log handler file ' . $handler . '.php');
380
    }
381
382
    require_once $file;
383
    $loghandlerinstance = new $handler();
384
    if (!$loghandlerinstance instanceof LogHandler) {
385
        throw new Exception('Log handler does not extend LogHandler');
386
    }
387
388
    if (empty($conf->loghandlers[$handler])) {
389
        $conf->loghandlers[$handler] = $loghandlerinstance;
390
    }
391
}
392
393
// Define object $langs
394
$langs = new Translate('..', $conf);
395
if (GETPOST('lang', 'aZ09')) {
396
    $langs->setDefaultLang(GETPOST('lang', 'aZ09'));
397
} else {
398
    $langs->setDefaultLang('auto');
399
}
400
401
402
/**
403
 * Load conf file (file must exists)
404
 *
405
 * @param string $dolibarr_main_document_root Root directory of Dolibarr bin files
406
 * @return    int                                                Return integer <0 if KO, >0 if OK
407
 */
408
function conf($dolibarr_main_document_root)
409
{
410
    global $conf;
411
    global $dolibarr_main_db_type;
412
    global $dolibarr_main_db_host;
413
    global $dolibarr_main_db_port;
414
    global $dolibarr_main_db_name;
415
    global $dolibarr_main_db_user;
416
    global $dolibarr_main_db_pass;
417
    global $dolibarr_main_db_collation;
418
    global $dolibarr_main_db_character_set;
419
    global $character_set_client;
420
    global $dolibarr_main_instance_unique_id;
421
    global $dolibarr_main_cookie_cryptkey;
422
423
    $conf = new Conf();
424
    $conf->db->type = trim($dolibarr_main_db_type);
425
    $conf->db->host = trim($dolibarr_main_db_host);
426
    $conf->db->port = trim($dolibarr_main_db_port);
427
    $conf->db->name = trim($dolibarr_main_db_name);
428
    $conf->db->user = trim($dolibarr_main_db_user);
429
    $conf->db->pass = (empty($dolibarr_main_db_pass) ? '' : trim($dolibarr_main_db_pass));
430
431
    // Mysql driver support has been removed in favor of mysqli
432
    if ($conf->db->type == 'mysql') {
433
        $conf->db->type = 'mysqli';
434
    }
435
    if (empty($character_set_client)) {
436
        $character_set_client = "UTF-8";
437
    }
438
    $conf->file->character_set_client = strtoupper($character_set_client);
439
    // Unique id of instance
440
    $conf->file->instance_unique_id = empty($dolibarr_main_instance_unique_id) ? (empty($dolibarr_main_cookie_cryptkey) ? '' : $dolibarr_main_cookie_cryptkey) : $dolibarr_main_instance_unique_id;
441
    if (empty($dolibarr_main_db_character_set)) {
442
        $dolibarr_main_db_character_set = ($conf->db->type == 'mysqli' ? 'utf8' : '');
443
    }
444
    $conf->db->character_set = $dolibarr_main_db_character_set;
445
    if (empty($dolibarr_main_db_collation)) {
446
        $dolibarr_main_db_collation = ($conf->db->type == 'mysqli' ? 'utf8_unicode_ci' : '');
447
    }
448
    $conf->db->dolibarr_main_db_collation = $dolibarr_main_db_collation;
449
    if (empty($dolibarr_main_db_encryption)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $dolibarr_main_db_encryption seems to never exist and therefore empty should always be true.
Loading history...
450
        $dolibarr_main_db_encryption = 0;
451
    }
452
    $conf->db->dolibarr_main_db_encryption = $dolibarr_main_db_encryption;
453
    if (empty($dolibarr_main_db_cryptkey)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $dolibarr_main_db_cryptkey seems to never exist and therefore empty should always be true.
Loading history...
454
        $dolibarr_main_db_cryptkey = '';
455
    }
456
    $conf->db->dolibarr_main_db_cryptkey = $dolibarr_main_db_cryptkey;
457
458
    // Force usage of log file for install and upgrades
459
    $conf->modules['syslog'] = 'syslog';
460
    $conf->global->SYSLOG_LEVEL = constant('LOG_DEBUG');
461
    if (!defined('SYSLOG_HANDLERS')) {
462
        define('SYSLOG_HANDLERS', '["mod_syslog_file"]');
463
    }
464
    if (!defined('SYSLOG_FILE')) {    // To avoid warning on systems with constant already defined
465
        if (@is_writable('/tmp')) {
466
            define('SYSLOG_FILE', '/tmp/dolibarr_install.log');
467
        } elseif (!empty($_ENV["TMP"]) && @is_writable($_ENV["TMP"])) {
468
            define('SYSLOG_FILE', $_ENV["TMP"] . '/dolibarr_install.log');
469
        } elseif (!empty($_ENV["TEMP"]) && @is_writable($_ENV["TEMP"])) {
470
            define('SYSLOG_FILE', $_ENV["TEMP"] . '/dolibarr_install.log');
471
        } elseif (@is_writable('../../../../') && @file_exists('../../../../startdoliwamp.bat')) {
472
            define('SYSLOG_FILE', '../../../../dolibarr_install.log'); // For DoliWamp
473
        } elseif (@is_writable('../../')) {
474
            define('SYSLOG_FILE', '../../dolibarr_install.log'); // For others
475
        }
476
        //print 'SYSLOG_FILE='.SYSLOG_FILE;exit;
477
    }
478
    if (defined('SYSLOG_FILE')) {
479
        $conf->global->SYSLOG_FILE = constant('SYSLOG_FILE');
480
    }
481
    if (!defined('SYSLOG_FILE_NO_ERROR')) {
482
        define('SYSLOG_FILE_NO_ERROR', 1);
483
    }
484
    // We init log handler for install
485
    $handlers = array('mod_syslog_file');
486
    foreach ($handlers as $handler) {
487
        $file = DOL_DOCUMENT_ROOT . '/core/modules/syslog/' . $handler . '.php';
488
        if (!file_exists($file)) {
489
            throw new Exception('Missing log handler file ' . $handler . '.php');
490
        }
491
492
        require_once $file;
493
        $loghandlerinstance = new $handler();
494
        if (!$loghandlerinstance instanceof LogHandler) {
495
            throw new Exception('Log handler does not extend LogHandler');
496
        }
497
498
        if (empty($conf->loghandlers[$handler])) {
499
            $conf->loghandlers[$handler] = $loghandlerinstance;
500
        }
501
    }
502
503
    return 1;
504
}
505
506
507
/**
508
 * Show HTML header of install pages
509
 *
510
 * @param string $subtitle Title
511
 * @param string $next Next
512
 * @param string $action Action code ('set' or 'upgrade')
513
 * @param string $param Param
514
 * @param string $forcejqueryurl Set jquery relative URL (must end with / if defined)
515
 * @param string $csstable Css for table
516
 * @return    void
517
 */
518
function pHeader($subtitle, $next, $action = 'set', $param = '', $forcejqueryurl = '', $csstable = 'main-inside')
519
{
520
    global $conf;
521
    global $langs;
522
    $langs->load("main");
523
    $langs->load("admin");
524
    $langs->load("install");
525
526
    $jquerytheme = 'base';
527
528
    if ($forcejqueryurl) {
529
        $jQueryCustomPath = $forcejqueryurl;
530
        $jQueryUiCustomPath = $forcejqueryurl;
531
    } else {
532
        $jQueryCustomPath = (defined('JS_JQUERY') && constant('JS_JQUERY')) ? JS_JQUERY : false;
533
        $jQueryUiCustomPath = (defined('JS_JQUERY_UI') && constant('JS_JQUERY_UI')) ? JS_JQUERY_UI : false;
534
    }
535
536
    // We force the content charset
537
    header("Content-type: text/html; charset=" . $conf->file->character_set_client);
538
    header("X-Content-Type-Options: nosniff");
539
    header("X-Frame-Options: SAMEORIGIN"); // Frames allowed only if on same domain (stop some XSS attacks)
540
541
    $defaultcss = constant('DOL_URL_ROOT') . '/install/default.css';
542
    $logo = constant('DOL_URL_ROOT') . '/theme/alixar_rectangular_logo.svg';
543
544
    print '<!DOCTYPE HTML>' . "\n";
545
    print '<html>' . "\n";
546
    print '<head>' . "\n";
547
    print '<meta charset="' . $conf->file->character_set_client . '">' . "\n";
548
    print '<meta name="viewport" content="width=device-width, initial-scale=1.0">' . "\n";
549
    print '<meta name="generator" content="Dolibarr installer">' . "\n";
550
    print '<link rel="stylesheet" type="text/css" href="' . $defaultcss . '">' . "\n";
551
552
    print '<!-- Includes CSS for JQuery -->' . "\n";
553
    if ($jQueryUiCustomPath) {
554
        print '<link rel="stylesheet" type="text/css" href="' . $jQueryUiCustomPath . 'css/' . $jquerytheme . '/jquery-ui.min.css" />' . "\n"; // JQuery
555
    } else {
556
        print '<link rel="stylesheet" type="text/css" href="' . constant('DOL_URL_ROOT') . '/includes/jquery/css/' . $jquerytheme . '/jquery-ui.min.css" />' . "\n"; // JQuery
557
    }
558
559
    print '<!-- Includes JS for JQuery -->' . "\n";
560
    if ($jQueryCustomPath) {
561
        print '<script type="text/javascript" src="' . $jQueryCustomPath . 'jquery.min.js"></script>' . "\n";
562
    } else {
563
        print '<script type="text/javascript" src="' . constant('DOL_URL_ROOT') . '/includes/jquery/js/jquery.min.js"></script>' . "\n";
564
    }
565
    if ($jQueryUiCustomPath) {
566
        print '<script type="text/javascript" src="' . $jQueryUiCustomPath . 'jquery-ui.min.js"></script>' . "\n";
567
    } else {
568
        print '<script type="text/javascript" src="' . constant('DOL_URL_ROOT') . '/includes/jquery/js/jquery-ui.min.js"></script>' . "\n";
569
    }
570
571
    print '<title>' . $langs->trans("DolibarrSetup") . '</title>' . "\n";
572
    print '</head>' . "\n";
573
574
    print '<body>' . "\n";
575
576
    print '<div class="divlogoinstall" style="text-align:center">';
577
    print '<img class="imglogoinstall" src="' . $logo . '" alt="Dolibarr logo" width="300px"><br>';
578
    print DOL_VERSION;
579
    print '</div><br>';
580
581
    print '<span class="titre">' . $langs->trans("DolibarrSetup");
582
    if ($subtitle) {
583
        print ' - ' . $subtitle;
584
    }
585
    print '</span>' . "\n";
586
587
    print '<form name="forminstall" id="forminstall" class="centpercent" action="' . $next . '.php' . ($param ? '?' . $param : '') . '" method="POST"';
588
    if ($next == 'step5') {
589
        print ' autocomplete="off"';
590
    }
591
    print '>' . "\n";
592
    print '<input type="hidden" name="testpost" value="ok">' . "\n";
593
    print '<input type="hidden" name="action" value="' . $action . '">' . "\n";
594
595
    print '<div id="divinstall">';
596
597
    print '<table class="main centpercent"><tr><td>' . "\n";
598
599
    print '<table class="' . $csstable . ' centpercent"><tr><td>' . "\n";
600
}
601
602
/**
603
 * Print HTML footer of install pages
604
 *
605
 * @param integer $nonext 1=No button "Next step", 2=Show button but disabled with a link to enable
606
 * @param string $setuplang Language code
607
 * @param string $jscheckfunction Add a javascript check function
608
 * @param integer $withpleasewait Add also please wait tags
609
 * @param string $morehtml Add more HTML content
610
 * @return    void
611
 */
612
function pFooter($nonext = 0, $setuplang = '', $jscheckfunction = '', $withpleasewait = 0, $morehtml = '')
613
{
614
    global $conf, $langs;
615
616
    $langs->loadLangs(array("main", "other", "admin"));
617
618
    print '</td></tr></table>' . "\n";
619
    print '</td></tr></table>' . "\n";
620
621
    print '<!-- pFooter -->' . "\n";
622
623
    print $morehtml;
624
625
    print '</div>';
626
627
    if (!$nonext || ($nonext == '2')) {
628
        print '<div class="nextbutton" id="nextbutton">';
629
        if ($nonext == '2') {
630
            print '<span class="warning">';
631
            print $langs->trans("ErrorFoundDuringMigration", isset($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] . '&ignoreerrors=1' : '');
632
            print '</span>';
633
            print '<br><br>';
634
        }
635
636
        print '<input type="submit" ' . ($nonext == '2' ? 'disabled="disabled" ' : '') . 'value="' . $langs->trans("NextStep") . ' ->"';
637
        if ($jscheckfunction) {
638
            print ' onClick="return ' . $jscheckfunction . '();"';
639
        }
640
        print '>';
641
        print '</div>';
642
        if ($withpleasewait) {
643
            print '<div style="visibility: hidden;" class="pleasewait" id="pleasewait"><br>' . $langs->trans("NextStepMightLastALongTime") . '<br><br><div class="blinkwait">' . $langs->trans("PleaseBePatient") . '</div></div>';
644
        }
645
    }
646
    if ($setuplang) {
647
        print '<input type="hidden" name="selectlang" value="' . dol_escape_htmltag($setuplang) . '">';
648
    }
649
650
    print '</form><br>' . "\n";
651
652
    // If there is some logs in buffer to show
653
    if (isset($conf->logbuffer) && count($conf->logbuffer)) {
654
        print "\n";
655
        print "<!-- Start of log output\n";
656
        //print '<div class="hidden">'."\n";
657
        foreach ($conf->logbuffer as $logline) {
658
            print $logline . "<br>\n";
659
        }
660
        //print '</div>'."\n";
661
        print "End of log output -->\n";
662
        print "\n";
663
    }
664
665
    print '</body>' . "\n";
666
    print '</html>' . "\n";
667
}
668
669
/**
670
 * Log function for install pages
671
 *
672
 * @param string $message Message
673
 * @param int $level Level of log
674
 * @return    void
675
 */
676
function dolibarr_install_syslog($message, $level = LOG_DEBUG)
677
{
678
    if (!defined('LOG_DEBUG')) {
679
        define('LOG_DEBUG', 6);
680
    }
681
    dol_syslog($message, $level);
682
}
683
684
/**
685
 * Automatically detect Dolibarr's main document root
686
 *
687
 * @return string
688
 */
689
function detect_dolibarr_main_document_root()
690
{
691
    // If PHP is in CGI mode, SCRIPT_FILENAME is PHP's path.
692
    // Since that's not what we want, we suggest $_SERVER["DOCUMENT_ROOT"]
693
    if ($_SERVER["SCRIPT_FILENAME"] == 'php' || preg_match('/[\\/]php$/i', $_SERVER["SCRIPT_FILENAME"]) || preg_match('/php\.exe$/i', $_SERVER["SCRIPT_FILENAME"])) {
694
        $dolibarr_main_document_root = $_SERVER["DOCUMENT_ROOT"];
695
696
        if (!preg_match('/[\\/]dolibarr[\\/]htdocs$/i', $dolibarr_main_document_root)) {
697
            $dolibarr_main_document_root .= "/dolibarr/htdocs";
698
        }
699
    } else {
700
        // We assume /install to be under /htdocs, so we get the parent directory of the current directory
701
        $dolibarr_main_document_root = dirname(dirname($_SERVER["SCRIPT_FILENAME"]));
702
    }
703
704
    return $dolibarr_main_document_root;
705
}
706
707
/**
708
 * Automatically detect Dolibarr's main data root
709
 *
710
 * @param string $dolibarr_main_document_root Current main document root
711
 * @return string
712
 */
713
function detect_dolibarr_main_data_root($dolibarr_main_document_root)
714
{
715
    $dolibarr_main_data_root = preg_replace("/\/public\/htdocs$/", "", $dolibarr_main_document_root);
716
    $dolibarr_main_data_root .= "/documents";
717
    return $dolibarr_main_data_root;
718
}
719
720
/**
721
 * Automatically detect Dolibarr's main URL root
722
 *
723
 * @return string
724
 */
725
function detect_dolibarr_main_url_root()
726
{
727
    // If defined (Ie: Apache with Linux)
728
    if (isset($_SERVER["SCRIPT_URI"])) {
729
        $dolibarr_main_url_root = $_SERVER["SCRIPT_URI"];
730
    } elseif (isset($_SERVER["SERVER_URL"]) && isset($_SERVER["DOCUMENT_URI"])) {
731
        // If defined (Ie: Apache with Caudium)
732
        $dolibarr_main_url_root = $_SERVER["SERVER_URL"] . $_SERVER["DOCUMENT_URI"];
733
    } else {
734
        // If SCRIPT_URI, SERVER_URL, DOCUMENT_URI not defined (Ie: Apache 2.0.44 for Windows)
735
        $proto = ((!empty($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on') || (!empty($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443)) ? 'https' : 'http';
736
        if (!empty($_SERVER["HTTP_HOST"])) {
737
            $serverport = $_SERVER["HTTP_HOST"];
738
        } elseif (!empty($_SERVER["SERVER_NAME"])) {
739
            $serverport = $_SERVER["SERVER_NAME"];
740
        } else {
741
            $serverport = 'localhost';
742
        }
743
        $dolibarr_main_url_root = $proto . "://" . $serverport . $_SERVER["SCRIPT_NAME"];
744
    }
745
    // Clean proposed URL
746
    // We assume /install to be under /htdocs, so we get the parent path of the current URL
747
    $dolibarr_main_url_root = dirname(dirname($dolibarr_main_url_root));
748
749
    return $dolibarr_main_url_root;
750
}
751
752
/**
753
 * Replaces automatic database login by actual value
754
 *
755
 * @param string $force_install_databaserootlogin Login
756
 * @return string
757
 */
758
function parse_database_login($force_install_databaserootlogin)
759
{
760
    return preg_replace('/__SUPERUSERLOGIN__/', 'root', $force_install_databaserootlogin);
761
}
762
763
/**
764
 * Replaces automatic database password by actual value
765
 *
766
 * @param string $force_install_databaserootpass Password
767
 * @return string
768
 */
769
function parse_database_pass($force_install_databaserootpass)
770
{
771
    return preg_replace('/__SUPERUSERPASSWORD__/', '', $force_install_databaserootpass);
772
}
773