MDL-65453 core: fix behaviour of --skip-database option on install
[moodle.git] / admin / cli / install.php
CommitLineData
3b596dbf 1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * This script creates config.php file and prepares database.
20 *
21 * This script is not intended for beginners!
22 * Potential problems:
3b596dbf 23 * - su to apache account or sudo before execution
24 * - not compatible with Windows platform
25 *
b7315f35 26 * @package core
3b596dbf 27 * @subpackage cli
28 * @copyright 2009 Petr Skoda (http://skodak.org)
29 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30 */
31
28bd3d9a
PS
32define('CLI_SCRIPT', true);
33
34// extra execution prevention - we can not just require config.php here
3b596dbf 35if (isset($_SERVER['REMOTE_ADDR'])) {
28bd3d9a 36 exit(1);
3b596dbf 37}
38
c05a5099
PS
39// Force OPcache reset if used, we do not want any stale caches
40// when preparing test environment.
41if (function_exists('opcache_reset')) {
42 opcache_reset();
43}
44
5a411e81 45$help =
46"Command line Moodle installer, creates config.php and initializes database.
47Please note you must execute this script with the same uid as apache
48or use chmod/chown after installation.
49
50Site defaults may be changed via local/defaults.php.
51
52Options:
7be67681
DM
53--chmod=OCTAL-MODE Permissions of new directories created within dataroot.
54 Default is 2777. You may want to change it to 2770
55 or 2750 or 750. See chmod man page for details.
5a411e81 56--lang=CODE Installation and default site language.
57--wwwroot=URL Web address for the Moodle site,
58 required in non-interactive mode.
59--dataroot=DIR Location of the moodle data folder,
59ba2bb0
DM
60 must not be web accessible. Default is moodledata
61 in the parent directory.
5a411e81 62--dbtype=TYPE Database type. Default is mysqli
63--dbhost=HOST Database host. Default is localhost
64--dbname=NAME Database name. Default is moodle
65--dbuser=USERNAME Database user. Default is root
66--dbpass=PASSWORD Database password. Default is blank
1826d0ea
PS
67--dbport=NUMBER Use database port.
68--dbsocket=PATH Use database socket, 1 means default. Available for some databases only.
5a411e81 69--prefix=STRING Table prefix for above database tables. Default is mdl_
9632db7a
DM
70--fullname=STRING The fullname of the site
71--shortname=STRING The shortname of the site
65903c76 72--summary=STRING The summary to be displayed on the front page
7217676b
DM
73--adminuser=USERNAME Username for the moodle admin account. Default is admin
74--adminpass=PASSWORD Password for the moodle admin account,
5a411e81 75 required in non-interactive mode.
da992717 76--adminemail=STRING Email address for the moodle admin account.
6ef02f84 77--upgradekey=STRING The upgrade key to be set in the config.php, leave empty to not set it.
5a411e81 78--non-interactive No interactive questions, installation fails if any
79 problem encountered.
c31d94e8 80--agree-license Indicates agreement with software license,
5a411e81 81 required in non-interactive mode.
3d673fc4
DM
82--allow-unstable Install even if the version is not marked as stable yet,
83 required in non-interactive mode.
096fd596 84--skip-database Stop the installation before installing the database.
5a411e81 85-h, --help Print out this help
86
28bd3d9a
PS
87Example:
88\$sudo -u www-data /usr/bin/php admin/cli/install.php --lang=cs
c31d94e8 89"; //TODO: localize, mark as needed in install - to be translated later when everything is finished
3b596dbf 90
3b596dbf 91
b1d53365 92// distro specific customisation
1fcf0ca8 93$distrolibfile = __DIR__.'/../../install/distrolib.php';
b1d53365
AA
94$distro = null;
95if (file_exists($distrolibfile)) {
96 require_once($distrolibfile);
97 if (function_exists('distro_get_config')) {
98 $distro = distro_get_config();
99 }
100}
101
3b596dbf 102// Nothing to do if config.php exists
1fcf0ca8 103$configfile = __DIR__.'/../../config.php';
3b596dbf 104if (file_exists($configfile)) {
5a411e81 105 require($configfile);
c31d94e8 106 require_once($CFG->libdir.'/clilib.php');
107 list($options, $unrecognized) = cli_get_params(array('help'=>false), array('h'=>'help'));
108
109 if ($options['help']) {
110 echo $help;
111 echo "\n\n";
112 }
113
f433088d
PS
114 if ($DB->get_manager()->table_exists('config')) {
115 cli_error(get_string('clialreadyinstalled', 'install'));
116 } else {
117 cli_error(get_string('clialreadyconfigured', 'install'));
118 }
3b596dbf 119}
120
5a411e81 121$olddir = getcwd();
122
ce8df92d 123// change directory so that includes below work properly
5a411e81 124chdir(dirname($_SERVER['argv'][0]));
125
211c9008 126// Servers should define a default timezone in php.ini, but if they don't then make sure something is defined.
d6e7a63d
PS
127if (!function_exists('date_default_timezone_set') or !function_exists('date_default_timezone_get')) {
128 fwrite(STDERR, "Timezone functions are not available.\n");
129 exit(1);
211c9008 130}
d6e7a63d 131date_default_timezone_set(@date_default_timezone_get());
211c9008 132
3b596dbf 133// make sure PHP errors are displayed - helps with diagnosing of problems
134@error_reporting(E_ALL);
135@ini_set('display_errors', '1');
136// we need a lot of memory
137@ini_set('memory_limit', '128M');
138
460ebd6c
PS
139/** Used by library scripts to check they are being called by Moodle */
140define('MOODLE_INTERNAL', true);
141
e2e35e71 142// Disables all caching.
94ef67cf
SH
143define('CACHE_DISABLE_ALL', true);
144
1abf2f6a
PS
145define('PHPUNIT_TEST', false);
146
d7245e34
PS
147define('IGNORE_COMPONENT_CACHE', true);
148
64e57937
DP
149// Check that PHP is of a sufficient version as soon as possible.
150require_once(__DIR__.'/../../lib/phpminimumversionlib.php');
151moodle_require_minimum_php_version();
3b596dbf 152
153// set up configuration
1a4621d8 154global $CFG;
3b596dbf 155$CFG = new stdClass();
3a915b06 156$CFG->lang = 'en';
1fcf0ca8 157$CFG->dirroot = dirname(dirname(__DIR__));
3b596dbf 158$CFG->libdir = "$CFG->dirroot/lib";
159$CFG->wwwroot = "http://localhost";
469d4b7f 160$CFG->httpswwwroot = $CFG->wwwroot;
3b596dbf 161$CFG->docroot = 'http://docs.moodle.org';
fb344c2d 162$CFG->running_installer = true;
3a915b06 163$CFG->early_install_lang = true;
cf4cef7d 164$CFG->ostype = (stristr(PHP_OS, 'win') && !stristr(PHP_OS, 'darwin')) ? 'WINDOWS' : 'UNIX';
1826d0ea 165$CFG->dboptions = array();
96f81ea3
PS
166$CFG->debug = (E_ALL | E_STRICT);
167$CFG->debugdisplay = true;
168$CFG->debugdeveloper = true;
3a915b06 169
1fcf0ca8 170$parts = explode('/', str_replace('\\', '/', dirname(__DIR__)));
3b596dbf 171$CFG->admin = array_pop($parts);
172
3b596dbf 173//point pear include path to moodles lib/pear so that includes and requires will search there for files before anywhere else
174//the problem is that we need specific version of quickforms and hacked excel files :-(
175ini_set('include_path', $CFG->libdir.'/pear' . PATH_SEPARATOR . ini_get('include_path'));
176
1abf2f6a 177require_once($CFG->libdir.'/classes/component.php');
d534708f 178require_once($CFG->libdir.'/classes/text.php');
99a9d8d9
PS
179require_once($CFG->libdir.'/classes/string_manager.php');
180require_once($CFG->libdir.'/classes/string_manager_install.php');
181require_once($CFG->libdir.'/classes/string_manager_standard.php');
3b596dbf 182require_once($CFG->libdir.'/installlib.php');
183require_once($CFG->libdir.'/clilib.php');
184require_once($CFG->libdir.'/setuplib.php');
3b596dbf 185require_once($CFG->libdir.'/weblib.php');
186require_once($CFG->libdir.'/dmllib.php');
187require_once($CFG->libdir.'/moodlelib.php');
188require_once($CFG->libdir.'/deprecatedlib.php');
189require_once($CFG->libdir.'/adminlib.php');
3b596dbf 190require_once($CFG->libdir.'/componentlib.class.php');
468cc572 191require_once($CFG->dirroot.'/cache/lib.php');
3b596dbf 192
98d696b6
SH
193// Register our classloader, in theory somebody might want to replace it to load other hacked core classes.
194// Required because the database checks below lead to session interaction which is going to lead us to requiring autoloaded classes.
195if (defined('COMPONENT_CLASSLOADER')) {
196 spl_autoload_register(COMPONENT_CLASSLOADER);
197} else {
198 spl_autoload_register('core_component::classloader');
199}
200
3d673fc4
DM
201require($CFG->dirroot.'/version.php');
202$CFG->target_release = $release;
203
2e00d01d 204\core\session\manager::init_empty_session();
1a4621d8
PS
205global $SESSION;
206global $USER;
1a4621d8
PS
207
208global $COURSE;
209$COURSE = new stdClass();
210$COURSE->id = 1;
211
212global $SITE;
213$SITE = $COURSE;
214define('SITEID', 1);
215
3b596dbf 216//Database types
217$databases = array('mysqli' => moodle_database::get_driver_instance('mysqli', 'native'),
66ba391e 218 'auroramysql' => moodle_database::get_driver_instance('auroramysql', 'native'),
17601a7e 219 'mariadb'=> moodle_database::get_driver_instance('mariadb', 'native'),
3b596dbf 220 'pgsql' => moodle_database::get_driver_instance('pgsql', 'native'),
221 'oci' => moodle_database::get_driver_instance('oci', 'native'),
7e60d0d6 222 'sqlsrv' => moodle_database::get_driver_instance('sqlsrv', 'native'), // MS SQL*Server PHP driver
3b596dbf 223 );
224foreach ($databases as $type=>$database) {
225 if ($database->driver_installed() !== true) {
226 unset($databases[$type]);
227 }
228}
229if (empty($databases)) {
c31d94e8 230 $defaultdb = '';
231} else {
232 reset($databases);
233 $defaultdb = key($databases);
3b596dbf 234}
235
3b596dbf 236// now get cli options
7217676b
DM
237list($options, $unrecognized) = cli_get_params(
238 array(
b1d53365 239 'chmod' => isset($distro->directorypermissions) ? sprintf('%04o',$distro->directorypermissions) : '2777', // let distros set dir permissions
7217676b
DM
240 'lang' => $CFG->lang,
241 'wwwroot' => '',
1fcf0ca8 242 'dataroot' => empty($distro->dataroot) ? str_replace('\\', '/', dirname(dirname(dirname(__DIR__))).'/moodledata'): $distro->dataroot, // initialised later after including libs or by distro
b1d53365
AA
243 'dbtype' => empty($distro->dbtype) ? $defaultdb : $distro->dbtype, // let distro skip dbtype selection
244 'dbhost' => empty($distro->dbhost) ? 'localhost' : $distro->dbhost, // let distros set dbhost
7217676b 245 'dbname' => 'moodle',
b1d53365 246 'dbuser' => empty($distro->dbuser) ? 'root' : $distro->dbuser, // let distros set dbuser
7217676b 247 'dbpass' => '',
1826d0ea
PS
248 'dbport' => '',
249 'dbsocket' => '',
7217676b 250 'prefix' => 'mdl_',
9632db7a
DM
251 'fullname' => '',
252 'shortname' => '',
65903c76 253 'summary' => '',
7217676b
DM
254 'adminuser' => 'admin',
255 'adminpass' => '',
da992717 256 'adminemail' => '',
6ef02f84 257 'upgradekey' => '',
7217676b
DM
258 'non-interactive' => false,
259 'agree-license' => false,
3d673fc4 260 'allow-unstable' => false,
096fd596 261 'skip-database' => false,
7217676b
DM
262 'help' => false
263 ),
264 array(
265 'h' => 'help'
266 )
267);
3b596dbf 268
269$interactive = empty($options['non-interactive']);
d208ffb0 270$skipdatabase = $options['skip-database'];
3b596dbf 271
272// set up language
273$lang = clean_param($options['lang'], PARAM_SAFEDIR);
7d62bc24
DM
274$languages = get_string_manager()->get_list_of_translations();
275if (array_key_exists($lang, $languages)) {
3b596dbf 276 $CFG->lang = $lang;
3b596dbf 277}
278
279if ($unrecognized) {
c31d94e8 280 $unrecognized = implode("\n ", $unrecognized);
1494616f 281 cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
3b596dbf 282}
283
284if ($options['help']) {
3b596dbf 285 echo $help;
286 die;
287}
288
3b596dbf 289//Print header
394034ec
DM
290cli_logo();
291echo PHP_EOL;
c31d94e8 292echo get_string('cliinstallheader', 'install', $CFG->target_release)."\n";
3b596dbf 293
294//Fist select language
295if ($interactive) {
c31d94e8 296 cli_separator();
960b6529 297 // Do not put the langs into columns because it is not compatible with RTL.
3a915b06 298 $default = $CFG->lang;
7d62bc24
DM
299 cli_heading(get_string('chooselanguagehead', 'install'));
300 if (array_key_exists($default, $languages)) {
301 echo $default.' - '.$languages[$default]."\n";
302 }
303 if ($default !== 'en') {
304 echo 'en - English (en)'."\n";
305 }
306 echo '? - '.get_string('availablelangs', 'install')."\n";
3a915b06 307 $prompt = get_string('clitypevaluedefault', 'admin', $CFG->lang);
3b596dbf 308 $error = '';
309 do {
310 echo $error;
311 $input = cli_input($prompt, $default);
3b596dbf 312
7d62bc24
DM
313 if ($input === '?') {
314 echo implode("\n", $languages)."\n";
315 $error = "\n";
316
3b596dbf 317 } else {
7d62bc24
DM
318 $input = clean_param($input, PARAM_SAFEDIR);
319
320 if (!array_key_exists($input, $languages)) {
321 $error = get_string('cliincorrectvalueretry', 'admin')."\n";
322 } else {
323 $error = '';
324 }
3b596dbf 325 }
326 } while ($error !== '');
3a915b06 327 $CFG->lang = $input;
3b596dbf 328} else {
c31d94e8 329 // already selected and verified
3b596dbf 330}
331
7be67681
DM
332// Set directorypermissions first
333$chmod = octdec(clean_param($options['chmod'], PARAM_INT));
334if ($interactive) {
335 cli_separator();
6e175676 336 cli_heading(get_string('datarootpermission', 'install'));
7be67681
DM
337 $prompt = get_string('clitypevaluedefault', 'admin', decoct($chmod));
338 $error = '';
339 do {
340 echo $error;
b7315f35 341 $input = cli_input($prompt, decoct($chmod));
7be67681
DM
342 $input = octdec(clean_param($input, PARAM_INT));
343 if (empty($input)) {
344 $error = get_string('cliincorrectvalueretry', 'admin')."\n";
345 } else {
346 $error = '';
347 }
b7315f35 348 } while ($error !== '');
7be67681
DM
349 $chmod = $input;
350
351} else {
352 if (empty($chmod)) {
353 $a = (object)array('option' => 'chmod', 'value' => decoct($chmod));
354 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
355 }
356}
357$CFG->directorypermissions = $chmod;
7f0ffc54
PS
358$CFG->filepermissions = ($CFG->directorypermissions & 0666);
359$CFG->umaskpermissions = (($CFG->directorypermissions & 0777) ^ 0777);
3b596dbf 360
361//We need wwwroot before we test dataroot
362$wwwroot = clean_param($options['wwwroot'], PARAM_URL);
363$wwwroot = trim($wwwroot, '/');
364if ($interactive) {
c31d94e8 365 cli_separator();
366 cli_heading(get_string('wwwroot', 'install'));
3b596dbf 367 if (strpos($wwwroot, 'http') === 0) {
c31d94e8 368 $prompt = get_string('clitypevaluedefault', 'admin', $wwwroot);
3b596dbf 369 } else {
c31d94e8 370 $wwwroot = null;
371 $prompt = get_string('clitypevalue', 'admin');
3b596dbf 372 }
373 $error = '';
374 do {
375 echo $error;
376 $input = cli_input($prompt, $wwwroot);
377 $input = clean_param($input, PARAM_URL);
378 $input = trim($input, '/');
379 if (strpos($input, 'http') !== 0) {
c31d94e8 380 $error = get_string('cliincorrectvalueretry', 'admin')."\n";
3b596dbf 381 } else {
382 $error = '';
383 }
384 } while ($error !== '');
385 $wwwroot = $input;
386
387} else {
388 if (strpos($wwwroot, 'http') !== 0) {
c31d94e8 389 $a = (object)array('option'=>'wwwroot', 'value'=>$wwwroot);
390 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
3b596dbf 391 }
392}
393$CFG->wwwroot = $wwwroot;
469d4b7f 394$CFG->httpswwwroot = $CFG->wwwroot;
3b596dbf 395
396//We need dataroot before lang download
ad72df40 397$CFG->dataroot = $options['dataroot'];
3b596dbf 398if ($interactive) {
c31d94e8 399 cli_separator();
3b596dbf 400 $i=0;
401 while(is_dataroot_insecure()) {
402 $parrent = dirname($CFG->dataroot);
403 $i++;
404 if ($parrent == '/' or $parrent == '.' or preg_match('/^[a-z]:\\\?$/i', $parrent) or ($i > 100)) {
405 $CFG->dataroot = ''; //can not find secure location for dataroot
406 break;
407 }
408 $CFG->dataroot = dirname($parrent).'/moodledata';
409 }
c31d94e8 410 cli_heading(get_string('dataroot', 'install'));
3b596dbf 411 $error = '';
412 do {
413 if ($CFG->dataroot !== '') {
c31d94e8 414 $prompt = get_string('clitypevaluedefault', 'admin', $CFG->dataroot);
3b596dbf 415 } else {
c31d94e8 416 $prompt = get_string('clitypevalue', 'admin');
3b596dbf 417 }
418 echo $error;
419 $CFG->dataroot = cli_input($prompt, $CFG->dataroot);
420 if ($CFG->dataroot === '') {
c31d94e8 421 $error = get_string('cliincorrectvalueretry', 'admin')."\n";
3b596dbf 422 } else if (is_dataroot_insecure()) {
423 $CFG->dataroot = '';
a18d577d 424 $error = get_string('pathsunsecuredataroot', 'install')."\n";
3b596dbf 425 } else {
211c9008 426 if (install_init_dataroot($CFG->dataroot, $CFG->directorypermissions)) {
3b596dbf 427 $error = '';
428 } else {
59ba2bb0
DM
429 $a = (object)array('dataroot' => $CFG->dataroot);
430 $error = get_string('pathserrcreatedataroot', 'install', $a)."\n";
3b596dbf 431 }
432 }
433
434 } while ($error !== '');
435
436} else {
437 if (is_dataroot_insecure()) {
59ba2bb0 438 cli_error(get_string('pathsunsecuredataroot', 'install'));
c31d94e8 439 }
211c9008 440 if (!install_init_dataroot($CFG->dataroot, $CFG->directorypermissions)) {
59ba2bb0
DM
441 $a = (object)array('dataroot' => $CFG->dataroot);
442 cli_error(get_string('pathserrcreatedataroot', 'install', $a));
3b596dbf 443 }
444}
85b38061 445$CFG->tempdir = $CFG->dataroot.'/temp';
ef844148 446$CFG->backuptempdir = $CFG->tempdir.'/backup';
85b38061
PS
447$CFG->cachedir = $CFG->dataroot.'/cache';
448$CFG->localcachedir = $CFG->dataroot.'/localcache';
3b596dbf 449
74a4c9a9
DM
450// download required lang packs
451if ($CFG->lang !== 'en') {
452 $installer = new lang_installer($CFG->lang);
453 $results = $installer->run();
454 foreach ($results as $langcode => $langstatus) {
455 if ($langstatus === lang_installer::RESULT_DOWNLOADERROR) {
456 $a = new stdClass();
457 $a->url = $installer->lang_pack_url($langcode);
458 $a->dest = $CFG->dataroot.'/lang';
459 cli_problem(get_string('remotedownloaderror', 'error', $a));
3b596dbf 460 }
461 }
3b596dbf 462}
3b596dbf 463
7d73574c 464// switch the string_manager instance to stop using install/lang/
3a915b06 465$CFG->early_install_lang = false;
877a172d
DM
466$CFG->langotherroot = $CFG->dataroot.'/lang';
467$CFG->langlocalroot = $CFG->dataroot.'/lang';
7d73574c 468get_string_manager(true);
3a915b06 469
3d673fc4
DM
470// make sure we are installing stable release or require a confirmation
471if (isset($maturity)) {
472 if (($maturity < MATURITY_STABLE) and !$options['allow-unstable']) {
473 $maturitylevel = get_string('maturity'.$maturity, 'admin');
474
475 if ($interactive) {
476 cli_separator();
477 cli_heading(get_string('notice'));
478 echo get_string('maturitycorewarning', 'admin', $maturitylevel) . PHP_EOL;
dc41abd8 479 echo get_string('morehelp') . ': ' . get_docs_url('admin/versions') . PHP_EOL;
7119e1a0 480 echo get_string('continue') . PHP_EOL;
3d673fc4
DM
481 $prompt = get_string('cliyesnoprompt', 'admin');
482 $input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin')));
483 if ($input == get_string('clianswerno', 'admin')) {
484 exit(1);
485 }
486 } else {
2da7fbc0
DM
487 cli_problem(get_string('maturitycorewarning', 'admin', $maturitylevel));
488 cli_error(get_string('maturityallowunstable', 'admin'));
3d673fc4
DM
489 }
490 }
491}
492
3b596dbf 493// ask for db type - show only drivers available
494if ($interactive) {
495 $options['dbtype'] = strtolower($options['dbtype']);
c31d94e8 496 cli_separator();
497 cli_heading(get_string('databasetypehead', 'install'));
3b596dbf 498 foreach ($databases as $type=>$database) {
c31d94e8 499 echo " $type \n";
3b596dbf 500 }
3b596dbf 501 if (!empty($databases[$options['dbtype']])) {
c31d94e8 502 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbtype']);
3b596dbf 503 } else {
c31d94e8 504 $prompt = get_string('clitypevalue', 'admin');
3b596dbf 505 }
3b596dbf 506 $CFG->dbtype = cli_input($prompt, $options['dbtype'], array_keys($databases));
507
508} else {
509 if (empty($databases[$options['dbtype']])) {
c31d94e8 510 $a = (object)array('option'=>'dbtype', 'value'=>$options['dbtype']);
511 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
3b596dbf 512 }
513 $CFG->dbtype = $options['dbtype'];
514}
515$database = $databases[$CFG->dbtype];
516
517
fffb043e
SR
518// We cannot do any validation until all DB connection data is provided.
519$hintdatabase = '';
520do {
521 echo $hintdatabase;
522
523 // Ask for db host.
524 if ($interactive) {
525 cli_separator();
526 cli_heading(get_string('databasehost', 'install'));
527 if ($options['dbhost'] !== '') {
528 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbhost']);
529 } else {
530 $prompt = get_string('clitypevalue', 'admin');
531 }
532 $CFG->dbhost = cli_input($prompt, $options['dbhost']);
533
3b596dbf 534 } else {
fffb043e 535 $CFG->dbhost = $options['dbhost'];
3b596dbf 536 }
3b596dbf 537
fffb043e
SR
538 // Ask for db name.
539 if ($interactive) {
540 cli_separator();
541 cli_heading(get_string('databasename', 'install'));
542 if ($options['dbname'] !== '') {
543 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbname']);
544 } else {
545 $prompt = get_string('clitypevalue', 'admin');
546 }
547 $CFG->dbname = cli_input($prompt, $options['dbname']);
3b596dbf 548
3b596dbf 549 } else {
fffb043e 550 $CFG->dbname = $options['dbname'];
3b596dbf 551 }
3b596dbf 552
fffb043e
SR
553 // Ask for db prefix.
554 if ($interactive) {
555 cli_separator();
556 cli_heading(get_string('dbprefix', 'install'));
557 //TODO: solve somehow the prefix trouble for oci.
558 if ($options['prefix'] !== '') {
559 $prompt = get_string('clitypevaluedefault', 'admin', $options['prefix']);
560 } else {
561 $prompt = get_string('clitypevalue', 'admin');
562 }
563 $CFG->prefix = cli_input($prompt, $options['prefix']);
3b596dbf 564
3b596dbf 565 } else {
fffb043e 566 $CFG->prefix = $options['prefix'];
3b596dbf 567 }
3b596dbf 568
fffb043e
SR
569 // Ask for db port.
570 if ($interactive) {
571 cli_separator();
572 cli_heading(get_string('databaseport', 'install'));
573 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbport']);
574 $CFG->dboptions['dbport'] = (int) cli_input($prompt, $options['dbport']);
3b596dbf 575
fffb043e
SR
576 } else {
577 $CFG->dboptions['dbport'] = (int) $options['dbport'];
578 }
579 if ($CFG->dboptions['dbport'] <= 0) {
580 $CFG->dboptions['dbport'] = '';
581 }
1826d0ea 582
fffb043e
SR
583 // Ask for db socket.
584 if ($CFG->ostype === 'WINDOWS') {
585 $CFG->dboptions['dbsocket'] = '';
1826d0ea 586
fffb043e
SR
587 } else if ($interactive and empty($CFG->dboptions['dbport'])) {
588 cli_separator();
589 cli_heading(get_string('databasesocket', 'install'));
590 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbsocket']);
591 $CFG->dboptions['dbsocket'] = cli_input($prompt, $options['dbsocket']);
1826d0ea 592
fffb043e
SR
593 } else {
594 $CFG->dboptions['dbsocket'] = $options['dbsocket'];
595 }
1826d0ea 596
fffb043e
SR
597 // Ask for db user.
598 if ($interactive) {
599 cli_separator();
600 cli_heading(get_string('databaseuser', 'install'));
601 if ($options['dbuser'] !== '') {
602 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbuser']);
603 } else {
604 $prompt = get_string('clitypevalue', 'admin');
605 }
606 $CFG->dbuser = cli_input($prompt, $options['dbuser']);
1826d0ea 607
3b596dbf 608 } else {
fffb043e 609 $CFG->dbuser = $options['dbuser'];
3b596dbf 610 }
3b596dbf 611
fffb043e
SR
612 // Ask for db password.
613 if ($interactive) {
614 cli_separator();
615 cli_heading(get_string('databasepass', 'install'));
3b596dbf 616
3b596dbf 617 if ($options['dbpass'] !== '') {
c31d94e8 618 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbpass']);
3b596dbf 619 } else {
c31d94e8 620 $prompt = get_string('clitypevalue', 'admin');
3b596dbf 621 }
622
623 $CFG->dbpass = cli_input($prompt, $options['dbpass']);
fffb043e
SR
624 if (function_exists('distro_pre_create_db')) { // Hook for distros needing to do something before DB creation.
625 $distro = distro_pre_create_db($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix,
626 array('dbpersist' => 0, 'dbport' => $CFG->dboptions['dbport'], 'dbsocket' => $CFG->dboptions['dbsocket']),
627 $distro);
b1d53365 628 }
fffb043e
SR
629 $hintdatabase = install_db_validate($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix,
630 array('dbpersist' => 0, 'dbport' => $CFG->dboptions['dbport'], 'dbsocket' => $CFG->dboptions['dbsocket']));
3b596dbf 631
fffb043e
SR
632 } else {
633 $CFG->dbpass = $options['dbpass'];
634 $hintdatabase = install_db_validate($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix,
635 array('dbpersist' => 0, 'dbport' => $CFG->dboptions['dbport'], 'dbsocket' => $CFG->dboptions['dbsocket']));
636 if ($hintdatabase !== '') {
637 cli_error(get_string('dbconnectionerror', 'install'));
638 }
3b596dbf 639 }
fffb043e 640} while ($hintdatabase !== '');
3b596dbf 641
d208ffb0
SL
642// If --skip-database option is provided, we do not need to ask for site fullname, shortname, adminuser, adminpass, adminemail.
643// These fields will be requested during the database install part.
644if (!$skipdatabase) {
645 // Ask for fullname.
646 if ($interactive) {
647 cli_separator();
648 cli_heading(get_string('fullsitename', 'moodle'));
9632db7a 649
d208ffb0
SL
650 if ($options['fullname'] !== '') {
651 $prompt = get_string('clitypevaluedefault', 'admin', $options['fullname']);
652 } else {
653 $prompt = get_string('clitypevalue', 'admin');
654 }
655
656 do {
657 $options['fullname'] = cli_input($prompt, $options['fullname']);
658 } while (empty($options['fullname']));
9632db7a 659 } else {
d208ffb0
SL
660 if (empty($options['fullname'])) {
661 $a = (object)['option' => 'fullname', 'value' => $options['fullname']];
662 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
663 }
9632db7a
DM
664 }
665
d208ffb0
SL
666 // Ask for shortname.
667 if ($interactive) {
668 cli_separator();
669 cli_heading(get_string('shortsitename', 'moodle'));
9632db7a 670
d208ffb0
SL
671 if ($options['shortname'] !== '') {
672 $prompt = get_string('clitypevaluedefault', 'admin', $options['shortname']);
673 } else {
674 $prompt = get_string('clitypevalue', 'admin');
675 }
9632db7a 676
d208ffb0
SL
677 do {
678 $options['shortname'] = cli_input($prompt, $options['shortname']);
679 } while (empty($options['shortname']));
9632db7a 680 } else {
d208ffb0
SL
681 if (empty($options['shortname'])) {
682 $a = (object)['option' => 'shortname', 'value' => $options['shortname']];
683 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
684 }
9632db7a
DM
685 }
686
d208ffb0
SL
687 // Ask for admin user name.
688 if ($interactive) {
689 cli_separator();
690 cli_heading(get_string('cliadminusername', 'install'));
691 if (!empty($options['adminuser'])) {
692 $prompt = get_string('clitypevaluedefault', 'admin', $options['adminuser']);
693 } else {
694 $prompt = get_string('clitypevalue', 'admin');
695 }
696 do {
697 $options['adminuser'] = cli_input($prompt, $options['adminuser']);
698 } while (empty($options['adminuser']) or $options['adminuser'] === 'guest');
699 } else {
700 if ((empty($options['adminuser']) || $options['adminuser'] === 'guest')) {
701 $a = (object)['option' => 'adminuser', 'value' => $options['adminuser']];
702 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
703 }
9632db7a 704 }
9632db7a 705
d208ffb0
SL
706 // Ask for admin user password.
707 if ($interactive) {
708 cli_separator();
709 cli_heading(get_string('cliadminpassword', 'install'));
7217676b 710 $prompt = get_string('clitypevalue', 'admin');
d208ffb0
SL
711 do {
712 $options['adminpass'] = cli_input($prompt);
713 } while (empty($options['adminpass']) or $options['adminpass'] === 'admin');
714 } else {
715 if ((empty($options['adminpass']) or $options['adminpass'] === 'admin')) {
716 $a = (object)['option' => 'adminpass', 'value' => $options['adminpass']];
717 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
718 }
7217676b 719 }
d208ffb0
SL
720
721 // Ask for the admin email address.
722 if ($interactive) {
723 cli_separator();
724 cli_heading(get_string('cliadminemail', 'install'));
725 $prompt = get_string('clitypevaluedefault', 'admin', $options['adminemail']);
726 $options['adminemail'] = cli_input($prompt, $options['adminemail']);
7217676b 727 }
7217676b 728
d208ffb0
SL
729 // Validate that the address provided was an e-mail address.
730 if (!empty($options['adminemail']) && !validate_email($options['adminemail'])) {
731 $a = (object)['option' => 'adminemail', 'value' => $options['adminemail']];
c31d94e8 732 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
3b596dbf 733 }
734}
735
6ef02f84
DM
736// Ask for the upgrade key.
737if ($interactive) {
738 cli_separator();
739 cli_heading(get_string('upgradekeyset', 'admin'));
740 if ($options['upgradekey'] !== '') {
741 $prompt = get_string('clitypevaluedefault', 'admin', $options['upgradekey']);
742 $options['upgradekey'] = cli_input($prompt, $options['upgradekey']);
743 } else {
744 $prompt = get_string('clitypevalue', 'admin');
745 $options['upgradekey'] = cli_input($prompt);
746 }
747}
748
749// Set the upgrade key if it was provided.
750if ($options['upgradekey'] !== '') {
751 $CFG->upgradekey = $options['upgradekey'];
752}
753
d208ffb0
SL
754// The user does not also need to pass agree-license when --skip-database is provided as the user will need to accept
755// the license again in the database install part.
756if (!$skipdatabase) {
757 if ($interactive) {
758 if (!$options['agree-license']) {
759 cli_separator();
760 cli_heading(get_string('copyrightnotice'));
761 echo "Moodle - Modular Object-Oriented Dynamic Learning Environment\n";
762 echo get_string('gpl3')."\n\n";
763 echo get_string('doyouagree')."\n";
764 $prompt = get_string('cliyesnoprompt', 'admin');
765 $input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin')));
766 if ($input == get_string('clianswerno', 'admin')) {
767 exit(1);
768 }
769 }
770 } else {
771 if (!$options['agree-license'] && !$skipdatabase) {
772 cli_error(get_string('climustagreelicense', 'install'));
b8523467 773 }
3b596dbf 774 }
775}
776
777// Finally we have all info needed for config.php
778$configphp = install_generate_configphp($database, $CFG);
779umask(0137);
780if (($fh = fopen($configfile, 'w')) !== false) {
781 fwrite($fh, $configphp);
782 fclose($fh);
783}
784
785if (!file_exists($configfile)) {
786 cli_error('Can not create config file.');
3b596dbf 787}
788
f433088d
PS
789// remember selected language
790$installlang = $CFG->lang;
791// return back to original dir before executing setup.php which changes the dir again
792chdir($olddir);
793// We have config.php, it is a real php script from now on :-)
794require($configfile);
795
796// use selected language
797$CFG->lang = $installlang;
798$SESSION->lang = $CFG->lang;
799
800require("$CFG->dirroot/version.php");
801
faadd326 802// Test environment first.
f433088d 803require_once($CFG->libdir . '/environmentlib.php');
faadd326
TH
804list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
805if (!$envstatus) {
806 $errors = environment_get_errors($environment_results);
807 cli_heading(get_string('environment', 'admin'));
808 foreach ($errors as $error) {
809 list($info, $report) = $error;
810 echo "!! $info !!\n$report\n\n";
811 }
812 exit(1);
813}
814
777781d1 815// Test plugin dependencies.
f1753a5b 816$failed = array();
e87214bd 817if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
f1753a5b 818 cli_problem(get_string('pluginscheckfailed', 'admin', array('pluginslist' => implode(', ', array_unique($failed)))));
faadd326
TH
819 cli_error(get_string('pluginschecktodo', 'admin'));
820}
821
d208ffb0 822if (!$skipdatabase) {
096fd596 823 install_cli_database($options, $interactive);
0f268f5d
RW
824 // This needs to happen at the end to ensure it occurs after all caches
825 // have been purged for the last time.
826 // This will build a cached version of the current theme for the user
827 // to immediately start browsing the site.
828 require_once($CFG->libdir.'/upgradelib.php');
829 upgrade_themes();
096fd596
CF
830} else {
831 echo get_string('cliskipdatabase', 'install')."\n";
832}
3b596dbf 833
b8523467 834echo get_string('cliinstallfinished', 'install')."\n";
835exit(0); // 0 means success