inc.php 27 KB

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