3 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
19 * This script creates config.php file and prepares database.
21 * This script is not intended for beginners!
23 * - su to apache account or sudo before execution
24 * - not compatible with Windows platform
28 * @copyright 2009 Petr Skoda (http://skodak.org)
29 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
32 define('CLI_SCRIPT', true);
34 // extra execution prevention - we can not just require config.php here
35 if (isset($_SERVER['REMOTE_ADDR'])) {
39 // Force OPcache reset if used, we do not want any stale caches
40 // when preparing test environment.
41 if (function_exists('opcache_reset')) {
46 "Command line Moodle installer, creates config.php and initializes database.
47 Please note you must execute this script with the same uid as apache
48 or use chmod/chown after installation.
50 Site defaults may be changed via local/defaults.php.
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.
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,
60 must not be web accessible. Default is moodledata
61 in the parent directory.
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
67 --dbport=NUMBER Use database port.
68 --dbsocket=PATH Use database socket, 1 means default. Available for some databases only.
69 --prefix=STRING Table prefix for above database tables. Default is mdl_
70 --fullname=STRING The fullname of the site
71 --shortname=STRING The shortname of the site
72 --summary=STRING The summary to be displayed on the front page
73 --adminuser=USERNAME Username for the moodle admin account. Default is admin
74 --adminpass=PASSWORD Password for the moodle admin account,
75 required in non-interactive mode.
76 --adminemail=STRING Email address for the moodle admin account.
77 --upgradekey=STRING The upgrade key to be set in the config.php, leave empty to not set it.
78 --non-interactive No interactive questions, installation fails if any
80 --agree-license Indicates agreement with software license,
81 required in non-interactive mode.
82 --allow-unstable Install even if the version is not marked as stable yet,
83 required in non-interactive mode.
84 --skip-database Stop the installation before installing the database.
85 -h, --help Print out this help
88 \$sudo -u www-data /usr/bin/php admin/cli/install.php --lang=cs
89 "; //TODO: localize, mark as needed in install - to be translated later when everything is finished
92 // distro specific customisation
93 $distrolibfile = __DIR__
.'/../../install/distrolib.php';
95 if (file_exists($distrolibfile)) {
96 require_once($distrolibfile);
97 if (function_exists('distro_get_config')) {
98 $distro = distro_get_config();
102 // Nothing to do if config.php exists
103 $configfile = __DIR__
.'/../../config.php';
104 if (file_exists($configfile)) {
105 require($configfile);
106 require_once($CFG->libdir
.'/clilib.php');
107 list($options, $unrecognized) = cli_get_params(array('help'=>false), array('h'=>'help'));
109 if ($options['help']) {
114 if ($DB->get_manager()->table_exists('config')) {
115 cli_error(get_string('clialreadyinstalled', 'install'));
117 cli_error(get_string('clialreadyconfigured', 'install'));
123 // change directory so that includes below work properly
124 chdir(dirname($_SERVER['argv'][0]));
126 // Servers should define a default timezone in php.ini, but if they don't then make sure something is defined.
127 if (!function_exists('date_default_timezone_set') or !function_exists('date_default_timezone_get')) {
128 fwrite(STDERR
, "Timezone functions are not available.\n");
131 date_default_timezone_set(@date_default_timezone_get
());
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');
139 /** Used by library scripts to check they are being called by Moodle */
140 define('MOODLE_INTERNAL', true);
142 // Disables all caching.
143 define('CACHE_DISABLE_ALL', true);
145 define('PHPUNIT_TEST', false);
147 define('IGNORE_COMPONENT_CACHE', true);
149 // Check that PHP is of a sufficient version as soon as possible.
150 require_once(__DIR__
.'/../../lib/phpminimumversionlib.php');
151 moodle_require_minimum_php_version();
153 // set up configuration
155 $CFG = new stdClass();
157 $CFG->dirroot
= dirname(dirname(__DIR__
));
158 $CFG->libdir
= "$CFG->dirroot/lib";
159 $CFG->wwwroot
= "http://localhost";
160 $CFG->httpswwwroot
= $CFG->wwwroot
;
161 $CFG->docroot
= 'http://docs.moodle.org';
162 $CFG->running_installer
= true;
163 $CFG->early_install_lang
= true;
164 $CFG->ostype
= (stristr(PHP_OS
, 'win') && !stristr(PHP_OS
, 'darwin')) ?
'WINDOWS' : 'UNIX';
165 $CFG->dboptions
= array();
166 $CFG->debug
= (E_ALL | E_STRICT
);
167 $CFG->debugdisplay
= true;
168 $CFG->debugdeveloper
= true;
170 $parts = explode('/', str_replace('\\', '/', dirname(__DIR__
)));
171 $CFG->admin
= array_pop($parts);
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 :-(
175 ini_set('include_path', $CFG->libdir
.'/pear' . PATH_SEPARATOR
. ini_get('include_path'));
177 require_once($CFG->libdir
.'/classes/component.php');
178 require_once($CFG->libdir
.'/classes/text.php');
179 require_once($CFG->libdir
.'/classes/string_manager.php');
180 require_once($CFG->libdir
.'/classes/string_manager_install.php');
181 require_once($CFG->libdir
.'/classes/string_manager_standard.php');
182 require_once($CFG->libdir
.'/installlib.php');
183 require_once($CFG->libdir
.'/clilib.php');
184 require_once($CFG->libdir
.'/setuplib.php');
185 require_once($CFG->libdir
.'/weblib.php');
186 require_once($CFG->libdir
.'/dmllib.php');
187 require_once($CFG->libdir
.'/moodlelib.php');
188 require_once($CFG->libdir
.'/deprecatedlib.php');
189 require_once($CFG->libdir
.'/adminlib.php');
190 require_once($CFG->libdir
.'/componentlib.class.php');
191 require_once($CFG->dirroot
.'/cache/lib.php');
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.
195 if (defined('COMPONENT_CLASSLOADER')) {
196 spl_autoload_register(COMPONENT_CLASSLOADER
);
198 spl_autoload_register('core_component::classloader');
201 require($CFG->dirroot
.'/version.php');
202 $CFG->target_release
= $release;
204 \core\session\manager
::init_empty_session();
209 $COURSE = new stdClass();
217 $databases = array('mysqli' => moodle_database
::get_driver_instance('mysqli', 'native'),
218 'auroramysql' => moodle_database
::get_driver_instance('auroramysql', 'native'),
219 'mariadb'=> moodle_database
::get_driver_instance('mariadb', 'native'),
220 'pgsql' => moodle_database
::get_driver_instance('pgsql', 'native'),
221 'oci' => moodle_database
::get_driver_instance('oci', 'native'),
222 'sqlsrv' => moodle_database
::get_driver_instance('sqlsrv', 'native'), // MS SQL*Server PHP driver
224 foreach ($databases as $type=>$database) {
225 if ($database->driver_installed() !== true) {
226 unset($databases[$type]);
229 if (empty($databases)) {
233 $defaultdb = key($databases);
236 // now get cli options
237 list($options, $unrecognized) = cli_get_params(
239 'chmod' => isset($distro->directorypermissions
) ?
sprintf('%04o',$distro->directorypermissions
) : '2777', // let distros set dir permissions
240 'lang' => $CFG->lang
,
242 'dataroot' => empty($distro->dataroot
) ?
str_replace('\\', '/', dirname(dirname(dirname(__DIR__
))).'/moodledata'): $distro->dataroot
, // initialised later after including libs or by distro
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
245 'dbname' => 'moodle',
246 'dbuser' => empty($distro->dbuser
) ?
'root' : $distro->dbuser
, // let distros set dbuser
254 'adminuser' => 'admin',
258 'non-interactive' => false,
259 'agree-license' => false,
260 'allow-unstable' => false,
261 'skip-database' => false,
269 $interactive = empty($options['non-interactive']);
270 $skipdatabase = $options['skip-database'];
273 $lang = clean_param($options['lang'], PARAM_SAFEDIR
);
274 $languages = get_string_manager()->get_list_of_translations();
275 if (array_key_exists($lang, $languages)) {
280 $unrecognized = implode("\n ", $unrecognized);
281 cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
284 if ($options['help']) {
292 echo get_string('cliinstallheader', 'install', $CFG->target_release
)."\n";
294 //Fist select language
297 // Do not put the langs into columns because it is not compatible with RTL.
298 $default = $CFG->lang
;
299 cli_heading(get_string('chooselanguagehead', 'install'));
300 if (array_key_exists($default, $languages)) {
301 echo $default.' - '.$languages[$default]."\n";
303 if ($default !== 'en') {
304 echo 'en - English (en)'."\n";
306 echo '? - '.get_string('availablelangs', 'install')."\n";
307 $prompt = get_string('clitypevaluedefault', 'admin', $CFG->lang
);
311 $input = cli_input($prompt, $default);
313 if ($input === '?') {
314 echo implode("\n", $languages)."\n";
318 $input = clean_param($input, PARAM_SAFEDIR
);
320 if (!array_key_exists($input, $languages)) {
321 $error = get_string('cliincorrectvalueretry', 'admin')."\n";
326 } while ($error !== '');
329 // already selected and verified
332 // Set directorypermissions first
333 $chmod = octdec(clean_param($options['chmod'], PARAM_INT
));
336 cli_heading(get_string('datarootpermission', 'install'));
337 $prompt = get_string('clitypevaluedefault', 'admin', decoct($chmod));
341 $input = cli_input($prompt, decoct($chmod));
342 $input = octdec(clean_param($input, PARAM_INT
));
344 $error = get_string('cliincorrectvalueretry', 'admin')."\n";
348 } while ($error !== '');
353 $a = (object)array('option' => 'chmod', 'value' => decoct($chmod));
354 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
357 $CFG->directorypermissions
= $chmod;
358 $CFG->filepermissions
= ($CFG->directorypermissions
& 0666);
359 $CFG->umaskpermissions
= (($CFG->directorypermissions
& 0777) ^
0777);
361 //We need wwwroot before we test dataroot
362 $wwwroot = clean_param($options['wwwroot'], PARAM_URL
);
363 $wwwroot = trim($wwwroot, '/');
366 cli_heading(get_string('wwwroot', 'install'));
367 if (strpos($wwwroot, 'http') === 0) {
368 $prompt = get_string('clitypevaluedefault', 'admin', $wwwroot);
371 $prompt = get_string('clitypevalue', 'admin');
376 $input = cli_input($prompt, $wwwroot);
377 $input = clean_param($input, PARAM_URL
);
378 $input = trim($input, '/');
379 if (strpos($input, 'http') !== 0) {
380 $error = get_string('cliincorrectvalueretry', 'admin')."\n";
384 } while ($error !== '');
388 if (strpos($wwwroot, 'http') !== 0) {
389 $a = (object)array('option'=>'wwwroot', 'value'=>$wwwroot);
390 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
393 $CFG->wwwroot
= $wwwroot;
394 $CFG->httpswwwroot
= $CFG->wwwroot
;
396 //We need dataroot before lang download
397 $CFG->dataroot
= $options['dataroot'];
401 while(is_dataroot_insecure()) {
402 $parrent = dirname($CFG->dataroot
);
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
408 $CFG->dataroot
= dirname($parrent).'/moodledata';
410 cli_heading(get_string('dataroot', 'install'));
413 if ($CFG->dataroot
!== '') {
414 $prompt = get_string('clitypevaluedefault', 'admin', $CFG->dataroot
);
416 $prompt = get_string('clitypevalue', 'admin');
419 $CFG->dataroot
= cli_input($prompt, $CFG->dataroot
);
420 if ($CFG->dataroot
=== '') {
421 $error = get_string('cliincorrectvalueretry', 'admin')."\n";
422 } else if (is_dataroot_insecure()) {
424 $error = get_string('pathsunsecuredataroot', 'install')."\n";
426 if (install_init_dataroot($CFG->dataroot
, $CFG->directorypermissions
)) {
429 $a = (object)array('dataroot' => $CFG->dataroot
);
430 $error = get_string('pathserrcreatedataroot', 'install', $a)."\n";
434 } while ($error !== '');
437 if (is_dataroot_insecure()) {
438 cli_error(get_string('pathsunsecuredataroot', 'install'));
440 if (!install_init_dataroot($CFG->dataroot
, $CFG->directorypermissions
)) {
441 $a = (object)array('dataroot' => $CFG->dataroot
);
442 cli_error(get_string('pathserrcreatedataroot', 'install', $a));
445 $CFG->tempdir
= $CFG->dataroot
.'/temp';
446 $CFG->backuptempdir
= $CFG->tempdir
.'/backup';
447 $CFG->cachedir
= $CFG->dataroot
.'/cache';
448 $CFG->localcachedir
= $CFG->dataroot
.'/localcache';
450 // download required lang packs
451 if ($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
) {
457 $a->url
= $installer->lang_pack_url($langcode);
458 $a->dest
= $CFG->dataroot
.'/lang';
459 cli_problem(get_string('remotedownloaderror', 'error', $a));
464 // switch the string_manager instance to stop using install/lang/
465 $CFG->early_install_lang
= false;
466 $CFG->langotherroot
= $CFG->dataroot
.'/lang';
467 $CFG->langlocalroot
= $CFG->dataroot
.'/lang';
468 get_string_manager(true);
470 // make sure we are installing stable release or require a confirmation
471 if (isset($maturity)) {
472 if (($maturity < MATURITY_STABLE
) and !$options['allow-unstable']) {
473 $maturitylevel = get_string('maturity'.$maturity, 'admin');
477 cli_heading(get_string('notice'));
478 echo get_string('maturitycorewarning', 'admin', $maturitylevel) . PHP_EOL
;
479 echo get_string('morehelp') . ': ' . get_docs_url('admin/versions') . PHP_EOL
;
480 echo get_string('continue') . PHP_EOL
;
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')) {
487 cli_problem(get_string('maturitycorewarning', 'admin', $maturitylevel));
488 cli_error(get_string('maturityallowunstable', 'admin'));
493 // ask for db type - show only drivers available
495 $options['dbtype'] = strtolower($options['dbtype']);
497 cli_heading(get_string('databasetypehead', 'install'));
498 foreach ($databases as $type=>$database) {
501 if (!empty($databases[$options['dbtype']])) {
502 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbtype']);
504 $prompt = get_string('clitypevalue', 'admin');
506 $CFG->dbtype
= cli_input($prompt, $options['dbtype'], array_keys($databases));
509 if (empty($databases[$options['dbtype']])) {
510 $a = (object)array('option'=>'dbtype', 'value'=>$options['dbtype']);
511 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
513 $CFG->dbtype
= $options['dbtype'];
515 $database = $databases[$CFG->dbtype
];
518 // We cannot do any validation until all DB connection data is provided.
526 cli_heading(get_string('databasehost', 'install'));
527 if ($options['dbhost'] !== '') {
528 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbhost']);
530 $prompt = get_string('clitypevalue', 'admin');
532 $CFG->dbhost
= cli_input($prompt, $options['dbhost']);
535 $CFG->dbhost
= $options['dbhost'];
541 cli_heading(get_string('databasename', 'install'));
542 if ($options['dbname'] !== '') {
543 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbname']);
545 $prompt = get_string('clitypevalue', 'admin');
547 $CFG->dbname
= cli_input($prompt, $options['dbname']);
550 $CFG->dbname
= $options['dbname'];
553 // Ask for db prefix.
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']);
561 $prompt = get_string('clitypevalue', 'admin');
563 $CFG->prefix
= cli_input($prompt, $options['prefix']);
566 $CFG->prefix
= $options['prefix'];
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']);
577 $CFG->dboptions
['dbport'] = (int) $options['dbport'];
579 if ($CFG->dboptions
['dbport'] <= 0) {
580 $CFG->dboptions
['dbport'] = '';
583 // Ask for db socket.
584 if ($CFG->ostype
=== 'WINDOWS') {
585 $CFG->dboptions
['dbsocket'] = '';
587 } else if ($interactive and empty($CFG->dboptions
['dbport'])) {
589 cli_heading(get_string('databasesocket', 'install'));
590 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbsocket']);
591 $CFG->dboptions
['dbsocket'] = cli_input($prompt, $options['dbsocket']);
594 $CFG->dboptions
['dbsocket'] = $options['dbsocket'];
600 cli_heading(get_string('databaseuser', 'install'));
601 if ($options['dbuser'] !== '') {
602 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbuser']);
604 $prompt = get_string('clitypevalue', 'admin');
606 $CFG->dbuser
= cli_input($prompt, $options['dbuser']);
609 $CFG->dbuser
= $options['dbuser'];
612 // Ask for db password.
615 cli_heading(get_string('databasepass', 'install'));
617 if ($options['dbpass'] !== '') {
618 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbpass']);
620 $prompt = get_string('clitypevalue', 'admin');
623 $CFG->dbpass
= cli_input($prompt, $options['dbpass']);
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']),
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']));
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'));
640 } while ($hintdatabase !== '');
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.
644 if (!$skipdatabase) {
648 cli_heading(get_string('fullsitename', 'moodle'));
650 if ($options['fullname'] !== '') {
651 $prompt = get_string('clitypevaluedefault', 'admin', $options['fullname']);
653 $prompt = get_string('clitypevalue', 'admin');
657 $options['fullname'] = cli_input($prompt, $options['fullname']);
658 } while (empty($options['fullname']));
660 if (empty($options['fullname'])) {
661 $a = (object)['option' => 'fullname', 'value' => $options['fullname']];
662 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
666 // Ask for shortname.
669 cli_heading(get_string('shortsitename', 'moodle'));
671 if ($options['shortname'] !== '') {
672 $prompt = get_string('clitypevaluedefault', 'admin', $options['shortname']);
674 $prompt = get_string('clitypevalue', 'admin');
678 $options['shortname'] = cli_input($prompt, $options['shortname']);
679 } while (empty($options['shortname']));
681 if (empty($options['shortname'])) {
682 $a = (object)['option' => 'shortname', 'value' => $options['shortname']];
683 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
687 // Ask for admin user name.
690 cli_heading(get_string('cliadminusername', 'install'));
691 if (!empty($options['adminuser'])) {
692 $prompt = get_string('clitypevaluedefault', 'admin', $options['adminuser']);
694 $prompt = get_string('clitypevalue', 'admin');
697 $options['adminuser'] = cli_input($prompt, $options['adminuser']);
698 } while (empty($options['adminuser']) or $options['adminuser'] === 'guest');
700 if ((empty($options['adminuser']) ||
$options['adminuser'] === 'guest')) {
701 $a = (object)['option' => 'adminuser', 'value' => $options['adminuser']];
702 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
706 // Ask for admin user password.
709 cli_heading(get_string('cliadminpassword', 'install'));
710 $prompt = get_string('clitypevalue', 'admin');
712 $options['adminpass'] = cli_input($prompt);
713 } while (empty($options['adminpass']) or $options['adminpass'] === 'admin');
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));
721 // Ask for the admin email address.
724 cli_heading(get_string('cliadminemail', 'install'));
725 $prompt = get_string('clitypevaluedefault', 'admin', $options['adminemail']);
726 $options['adminemail'] = cli_input($prompt, $options['adminemail']);
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']];
732 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
736 // Ask for the upgrade key.
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']);
744 $prompt = get_string('clitypevalue', 'admin');
745 $options['upgradekey'] = cli_input($prompt);
749 // Set the upgrade key if it was provided.
750 if ($options['upgradekey'] !== '') {
751 $CFG->upgradekey
= $options['upgradekey'];
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.
756 if (!$skipdatabase) {
758 if (!$options['agree-license']) {
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')) {
771 if (!$options['agree-license'] && !$skipdatabase) {
772 cli_error(get_string('climustagreelicense', 'install'));
777 // Finally we have all info needed for config.php
778 $configphp = install_generate_configphp($database, $CFG);
780 if (($fh = fopen($configfile, 'w')) !== false) {
781 fwrite($fh, $configphp);
785 if (!file_exists($configfile)) {
786 cli_error('Can not create config file.');
789 // remember selected language
790 $installlang = $CFG->lang
;
791 // return back to original dir before executing setup.php which changes the dir again
793 // We have config.php, it is a real php script from now on :-)
794 require($configfile);
796 // use selected language
797 $CFG->lang
= $installlang;
798 $SESSION->lang
= $CFG->lang
;
800 require("$CFG->dirroot/version.php");
802 // Test environment first.
803 require_once($CFG->libdir
. '/environmentlib.php');
804 list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE
);
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";
815 // Test plugin dependencies.
817 if (!core_plugin_manager
::instance()->all_plugins_ok($version, $failed)) {
818 cli_problem(get_string('pluginscheckfailed', 'admin', array('pluginslist' => implode(', ', array_unique($failed)))));
819 cli_error(get_string('pluginschecktodo', 'admin'));
822 if (!$skipdatabase) {
823 install_cli_database($options, $interactive);
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');
831 echo get_string('cliskipdatabase', 'install')."\n";
834 echo get_string('cliinstallfinished', 'install')."\n";
835 exit(0); // 0 means success