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
150 if (version_compare(phpversion(), "5.6.5") < 0) {
151 $phpversion = phpversion();
152 // do NOT localise - lang strings would not work here and we CAN NOT move it after installib
153 fwrite(STDERR, "Moodle 3.2 or later requires at least PHP 5.6.5 (currently using version $phpversion).\n");
154 fwrite(STDERR, "Please upgrade your server software or install older Moodle version.\n");
158 // set up configuration
160 $CFG = new stdClass();
162 $CFG->dirroot = dirname(dirname(__DIR__));
163 $CFG->libdir = "$CFG->dirroot/lib";
164 $CFG->wwwroot = "http://localhost";
165 $CFG->httpswwwroot = $CFG->wwwroot;
166 $CFG->docroot = 'http://docs.moodle.org';
167 $CFG->running_installer = true;
168 $CFG->early_install_lang = true;
169 $CFG->ostype = (stristr(PHP_OS, 'win') && !stristr(PHP_OS, 'darwin')) ? 'WINDOWS' : 'UNIX';
170 $CFG->dboptions = array();
171 $CFG->debug = (E_ALL | E_STRICT);
172 $CFG->debugdisplay = true;
173 $CFG->debugdeveloper = true;
175 $parts = explode('/', str_replace('\\', '/', dirname(__DIR__)));
176 $CFG->admin = array_pop($parts);
178 //point pear include path to moodles lib/pear so that includes and requires will search there for files before anywhere else
179 //the problem is that we need specific version of quickforms and hacked excel files :-(
180 ini_set('include_path', $CFG->libdir.'/pear' . PATH_SEPARATOR . ini_get('include_path'));
182 require_once($CFG->libdir.'/classes/component.php');
183 require_once($CFG->libdir.'/classes/text.php');
184 require_once($CFG->libdir.'/classes/string_manager.php');
185 require_once($CFG->libdir.'/classes/string_manager_install.php');
186 require_once($CFG->libdir.'/classes/string_manager_standard.php');
187 require_once($CFG->libdir.'/installlib.php');
188 require_once($CFG->libdir.'/clilib.php');
189 require_once($CFG->libdir.'/setuplib.php');
190 require_once($CFG->libdir.'/weblib.php');
191 require_once($CFG->libdir.'/dmllib.php');
192 require_once($CFG->libdir.'/moodlelib.php');
193 require_once($CFG->libdir.'/deprecatedlib.php');
194 require_once($CFG->libdir.'/adminlib.php');
195 require_once($CFG->libdir.'/componentlib.class.php');
196 require_once($CFG->dirroot.'/cache/lib.php');
198 // Register our classloader, in theory somebody might want to replace it to load other hacked core classes.
199 // Required because the database checks below lead to session interaction which is going to lead us to requiring autoloaded classes.
200 if (defined('COMPONENT_CLASSLOADER')) {
201 spl_autoload_register(COMPONENT_CLASSLOADER);
203 spl_autoload_register('core_component::classloader');
206 require($CFG->dirroot.'/version.php');
207 $CFG->target_release = $release;
209 \core\session\manager::init_empty_session();
214 $COURSE = new stdClass();
222 $databases = array('mysqli' => moodle_database::get_driver_instance('mysqli', 'native'),
223 'mariadb'=> moodle_database::get_driver_instance('mariadb', 'native'),
224 'pgsql' => moodle_database::get_driver_instance('pgsql', 'native'),
225 'oci' => moodle_database::get_driver_instance('oci', 'native'),
226 'sqlsrv' => moodle_database::get_driver_instance('sqlsrv', 'native'), // MS SQL*Server PHP driver
227 'mssql' => moodle_database::get_driver_instance('mssql', 'native'), // FreeTDS driver
229 foreach ($databases as $type=>$database) {
230 if ($database->driver_installed() !== true) {
231 unset($databases[$type]);
234 if (empty($databases)) {
238 $defaultdb = key($databases);
241 // now get cli options
242 list($options, $unrecognized) = cli_get_params(
244 'chmod' => isset($distro->directorypermissions) ? sprintf('%04o',$distro->directorypermissions) : '2777', // let distros set dir permissions
245 'lang' => $CFG->lang,
247 'dataroot' => empty($distro->dataroot) ? str_replace('\\', '/', dirname(dirname(dirname(__DIR__))).'/moodledata'): $distro->dataroot, // initialised later after including libs or by distro
248 'dbtype' => empty($distro->dbtype) ? $defaultdb : $distro->dbtype, // let distro skip dbtype selection
249 'dbhost' => empty($distro->dbhost) ? 'localhost' : $distro->dbhost, // let distros set dbhost
250 'dbname' => 'moodle',
251 'dbuser' => empty($distro->dbuser) ? 'root' : $distro->dbuser, // let distros set dbuser
259 'adminuser' => 'admin',
263 'non-interactive' => false,
264 'agree-license' => false,
265 'allow-unstable' => false,
266 'skip-database' => false,
274 $interactive = empty($options['non-interactive']);
277 $lang = clean_param($options['lang'], PARAM_SAFEDIR);
278 $languages = get_string_manager()->get_list_of_translations();
279 if (array_key_exists($lang, $languages)) {
284 $unrecognized = implode("\n ", $unrecognized);
285 cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
288 if ($options['help']) {
296 echo get_string('cliinstallheader', 'install', $CFG->target_release)."\n";
298 //Fist select language
301 // Do not put the langs into columns because it is not compatible with RTL.
302 $default = $CFG->lang;
303 cli_heading(get_string('chooselanguagehead', 'install'));
304 if (array_key_exists($default, $languages)) {
305 echo $default.' - '.$languages[$default]."\n";
307 if ($default !== 'en') {
308 echo 'en - English (en)'."\n";
310 echo '? - '.get_string('availablelangs', 'install')."\n";
311 $prompt = get_string('clitypevaluedefault', 'admin', $CFG->lang);
315 $input = cli_input($prompt, $default);
317 if ($input === '?') {
318 echo implode("\n", $languages)."\n";
322 $input = clean_param($input, PARAM_SAFEDIR);
324 if (!array_key_exists($input, $languages)) {
325 $error = get_string('cliincorrectvalueretry', 'admin')."\n";
330 } while ($error !== '');
333 // already selected and verified
336 // Set directorypermissions first
337 $chmod = octdec(clean_param($options['chmod'], PARAM_INT));
340 cli_heading(get_string('datarootpermission', 'install'));
341 $prompt = get_string('clitypevaluedefault', 'admin', decoct($chmod));
345 $input = cli_input($prompt, decoct($chmod));
346 $input = octdec(clean_param($input, PARAM_INT));
348 $error = get_string('cliincorrectvalueretry', 'admin')."\n";
352 } while ($error !== '');
357 $a = (object)array('option' => 'chmod', 'value' => decoct($chmod));
358 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
361 $CFG->directorypermissions = $chmod;
362 $CFG->filepermissions = ($CFG->directorypermissions & 0666);
363 $CFG->umaskpermissions = (($CFG->directorypermissions & 0777) ^ 0777);
365 //We need wwwroot before we test dataroot
366 $wwwroot = clean_param($options['wwwroot'], PARAM_URL);
367 $wwwroot = trim($wwwroot, '/');
370 cli_heading(get_string('wwwroot', 'install'));
371 if (strpos($wwwroot, 'http') === 0) {
372 $prompt = get_string('clitypevaluedefault', 'admin', $wwwroot);
375 $prompt = get_string('clitypevalue', 'admin');
380 $input = cli_input($prompt, $wwwroot);
381 $input = clean_param($input, PARAM_URL);
382 $input = trim($input, '/');
383 if (strpos($input, 'http') !== 0) {
384 $error = get_string('cliincorrectvalueretry', 'admin')."\n";
388 } while ($error !== '');
392 if (strpos($wwwroot, 'http') !== 0) {
393 $a = (object)array('option'=>'wwwroot', 'value'=>$wwwroot);
394 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
397 $CFG->wwwroot = $wwwroot;
398 $CFG->httpswwwroot = $CFG->wwwroot;
401 //We need dataroot before lang download
402 $CFG->dataroot = $options['dataroot'];
406 while(is_dataroot_insecure()) {
407 $parrent = dirname($CFG->dataroot);
409 if ($parrent == '/' or $parrent == '.' or preg_match('/^[a-z]:\\\?$/i', $parrent) or ($i > 100)) {
410 $CFG->dataroot = ''; //can not find secure location for dataroot
413 $CFG->dataroot = dirname($parrent).'/moodledata';
415 cli_heading(get_string('dataroot', 'install'));
418 if ($CFG->dataroot !== '') {
419 $prompt = get_string('clitypevaluedefault', 'admin', $CFG->dataroot);
421 $prompt = get_string('clitypevalue', 'admin');
424 $CFG->dataroot = cli_input($prompt, $CFG->dataroot);
425 if ($CFG->dataroot === '') {
426 $error = get_string('cliincorrectvalueretry', 'admin')."\n";
427 } else if (is_dataroot_insecure()) {
429 $error = get_string('pathsunsecuredataroot', 'install')."\n";
431 if (install_init_dataroot($CFG->dataroot, $CFG->directorypermissions)) {
434 $a = (object)array('dataroot' => $CFG->dataroot);
435 $error = get_string('pathserrcreatedataroot', 'install', $a)."\n";
439 } while ($error !== '');
442 if (is_dataroot_insecure()) {
443 cli_error(get_string('pathsunsecuredataroot', 'install'));
445 if (!install_init_dataroot($CFG->dataroot, $CFG->directorypermissions)) {
446 $a = (object)array('dataroot' => $CFG->dataroot);
447 cli_error(get_string('pathserrcreatedataroot', 'install', $a));
450 $CFG->tempdir = $CFG->dataroot.'/temp';
451 $CFG->cachedir = $CFG->dataroot.'/cache';
452 $CFG->localcachedir = $CFG->dataroot.'/localcache';
454 // download required lang packs
455 if ($CFG->lang !== 'en') {
456 $installer = new lang_installer($CFG->lang);
457 $results = $installer->run();
458 foreach ($results as $langcode => $langstatus) {
459 if ($langstatus === lang_installer::RESULT_DOWNLOADERROR) {
461 $a->url = $installer->lang_pack_url($langcode);
462 $a->dest = $CFG->dataroot.'/lang';
463 cli_problem(get_string('remotedownloaderror', 'error', $a));
468 // switch the string_manager instance to stop using install/lang/
469 $CFG->early_install_lang = false;
470 $CFG->langotherroot = $CFG->dataroot.'/lang';
471 $CFG->langlocalroot = $CFG->dataroot.'/lang';
472 get_string_manager(true);
474 // make sure we are installing stable release or require a confirmation
475 if (isset($maturity)) {
476 if (($maturity < MATURITY_STABLE) and !$options['allow-unstable']) {
477 $maturitylevel = get_string('maturity'.$maturity, 'admin');
481 cli_heading(get_string('notice'));
482 echo get_string('maturitycorewarning', 'admin', $maturitylevel) . PHP_EOL;
483 echo get_string('morehelp') . ': ' . get_docs_url('admin/versions') . PHP_EOL;
484 echo get_string('continue') . PHP_EOL;
485 $prompt = get_string('cliyesnoprompt', 'admin');
486 $input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin')));
487 if ($input == get_string('clianswerno', 'admin')) {
491 cli_problem(get_string('maturitycorewarning', 'admin', $maturitylevel));
492 cli_error(get_string('maturityallowunstable', 'admin'));
497 // ask for db type - show only drivers available
499 $options['dbtype'] = strtolower($options['dbtype']);
501 cli_heading(get_string('databasetypehead', 'install'));
502 foreach ($databases as $type=>$database) {
505 if (!empty($databases[$options['dbtype']])) {
506 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbtype']);
508 $prompt = get_string('clitypevalue', 'admin');
510 $CFG->dbtype = cli_input($prompt, $options['dbtype'], array_keys($databases));
513 if (empty($databases[$options['dbtype']])) {
514 $a = (object)array('option'=>'dbtype', 'value'=>$options['dbtype']);
515 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
517 $CFG->dbtype = $options['dbtype'];
519 $database = $databases[$CFG->dbtype];
525 cli_heading(get_string('databasehost', 'install'));
526 if ($options['dbhost'] !== '') {
527 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbhost']);
529 $prompt = get_string('clitypevalue', 'admin');
531 $CFG->dbhost = cli_input($prompt, $options['dbhost']);
534 $CFG->dbhost = $options['dbhost'];
540 cli_heading(get_string('databasename', 'install'));
541 if ($options['dbname'] !== '') {
542 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbname']);
544 $prompt = get_string('clitypevalue', 'admin');
546 $CFG->dbname = cli_input($prompt, $options['dbname']);
549 $CFG->dbname = $options['dbname'];
555 cli_heading(get_string('dbprefix', 'install'));
556 //TODO: solve somehow the prefix trouble for oci
557 if ($options['prefix'] !== '') {
558 $prompt = get_string('clitypevaluedefault', 'admin', $options['prefix']);
560 $prompt = get_string('clitypevalue', 'admin');
562 $CFG->prefix = cli_input($prompt, $options['prefix']);
565 $CFG->prefix = $options['prefix'];
571 cli_heading(get_string('databaseport', 'install'));
572 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbport']);
573 $CFG->dboptions['dbport'] = (int)cli_input($prompt, $options['dbport']);
576 $CFG->dboptions['dbport'] = (int)$options['dbport'];
578 if ($CFG->dboptions['dbport'] <= 0) {
579 $CFG->dboptions['dbport'] = '';
583 if ($CFG->ostype === 'WINDOWS') {
584 $CFG->dboptions['dbsocket'] = '';
586 } else if ($interactive and empty($CFG->dboptions['dbport'])) {
588 cli_heading(get_string('databasesocket', 'install'));
589 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbsocket']);
590 $CFG->dboptions['dbsocket'] = cli_input($prompt, $options['dbsocket']);
593 $CFG->dboptions['dbsocket'] = $options['dbsocket'];
599 cli_heading(get_string('databaseuser', 'install'));
600 if ($options['dbuser'] !== '') {
601 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbuser']);
603 $prompt = get_string('clitypevalue', 'admin');
605 $CFG->dbuser = cli_input($prompt, $options['dbuser']);
608 $CFG->dbuser = $options['dbuser'];
611 // ask for db password
614 cli_heading(get_string('databasepass', 'install'));
616 if ($options['dbpass'] !== '') {
617 $prompt = get_string('clitypevaluedefault', 'admin', $options['dbpass']);
619 $prompt = get_string('clitypevalue', 'admin');
622 $CFG->dbpass = cli_input($prompt, $options['dbpass']);
623 if (function_exists('distro_pre_create_db')) { // Hook for distros needing to do something before DB creation
624 $distro = distro_pre_create_db($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, array('dbpersist'=>0, 'dbport'=>$CFG->dboptions['dbport'], 'dbsocket'=>$CFG->dboptions['dbsocket']), $distro);
626 $hint_database = install_db_validate($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, array('dbpersist'=>0, 'dbport'=>$CFG->dboptions['dbport'], 'dbsocket'=>$CFG->dboptions['dbsocket']));
627 } while ($hint_database !== '');
630 $CFG->dbpass = $options['dbpass'];
631 $hint_database = install_db_validate($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, array('dbpersist'=>0, 'dbport'=>$CFG->dboptions['dbport'], 'dbsocket'=>$CFG->dboptions['dbsocket']));
632 if ($hint_database !== '') {
633 cli_error(get_string('dbconnectionerror', 'install'));
640 cli_heading(get_string('fullsitename', 'moodle'));
642 if ($options['fullname'] !== '') {
643 $prompt = get_string('clitypevaluedefault', 'admin', $options['fullname']);
645 $prompt = get_string('clitypevalue', 'admin');
649 $options['fullname'] = cli_input($prompt, $options['fullname']);
650 } while (empty($options['fullname']));
652 if (empty($options['fullname'])) {
653 $a = (object)array('option'=>'fullname', 'value'=>$options['fullname']);
654 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
661 cli_heading(get_string('shortsitename', 'moodle'));
663 if ($options['shortname'] !== '') {
664 $prompt = get_string('clitypevaluedefault', 'admin', $options['shortname']);
666 $prompt = get_string('clitypevalue', 'admin');
670 $options['shortname'] = cli_input($prompt, $options['shortname']);
671 } while (empty($options['shortname']));
673 if (empty($options['shortname'])) {
674 $a = (object)array('option'=>'shortname', 'value'=>$options['shortname']);
675 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
679 // ask for admin user name
682 cli_heading(get_string('cliadminusername', 'install'));
683 if (!empty($options['adminuser'])) {
684 $prompt = get_string('clitypevaluedefault', 'admin', $options['adminuser']);
686 $prompt = get_string('clitypevalue', 'admin');
689 $options['adminuser'] = cli_input($prompt, $options['adminuser']);
690 } while (empty($options['adminuser']) or $options['adminuser'] === 'guest');
692 if (empty($options['adminuser']) or $options['adminuser'] === 'guest') {
693 $a = (object)array('option'=>'adminuser', 'value'=>$options['adminuser']);
694 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
698 // ask for admin user password
701 cli_heading(get_string('cliadminpassword', 'install'));
702 $prompt = get_string('clitypevalue', 'admin');
704 $options['adminpass'] = cli_input($prompt);
705 } while (empty($options['adminpass']) or $options['adminpass'] === 'admin');
707 if (empty($options['adminpass']) or $options['adminpass'] === 'admin') {
708 $a = (object)array('option'=>'adminpass', 'value'=>$options['adminpass']);
709 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
713 // Ask for the admin email address.
716 cli_heading(get_string('cliadminemail', 'install'));
717 $prompt = get_string('clitypevaluedefault', 'admin', $options['adminemail']);
718 $options['adminemail'] = cli_input($prompt);
721 // Validate that the address provided was an e-mail address.
722 if (!empty($options['adminemail']) && !validate_email($options['adminemail'])) {
723 $a = (object) array('option' => 'adminemail', 'value' => $options['adminemail']);
724 cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
727 // Ask for the upgrade key.
730 cli_heading(get_string('upgradekeyset', 'admin'));
731 if ($options['upgradekey'] !== '') {
732 $prompt = get_string('clitypevaluedefault', 'admin', $options['upgradekey']);
733 $options['upgradekey'] = cli_input($prompt, $options['upgradekey']);
735 $prompt = get_string('clitypevalue', 'admin');
736 $options['upgradekey'] = cli_input($prompt);
740 // Set the upgrade key if it was provided.
741 if ($options['upgradekey'] !== '') {
742 $CFG->upgradekey = $options['upgradekey'];
746 if (!$options['agree-license']) {
748 cli_heading(get_string('copyrightnotice'));
749 echo "Moodle - Modular Object-Oriented Dynamic Learning Environment\n";
750 echo get_string('gpl3')."\n\n";
751 echo get_string('doyouagree')."\n";
752 $prompt = get_string('cliyesnoprompt', 'admin');
753 $input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin')));
754 if ($input == get_string('clianswerno', 'admin')) {
759 if (!$options['agree-license']) {
760 cli_error(get_string('climustagreelicense', 'install'));
764 // Finally we have all info needed for config.php
765 $configphp = install_generate_configphp($database, $CFG);
767 if (($fh = fopen($configfile, 'w')) !== false) {
768 fwrite($fh, $configphp);
772 if (!file_exists($configfile)) {
773 cli_error('Can not create config file.');
776 // remember selected language
777 $installlang = $CFG->lang;
778 // return back to original dir before executing setup.php which changes the dir again
780 // We have config.php, it is a real php script from now on :-)
781 require($configfile);
783 // use selected language
784 $CFG->lang = $installlang;
785 $SESSION->lang = $CFG->lang;
787 require("$CFG->dirroot/version.php");
789 // Test environment first.
790 require_once($CFG->libdir . '/environmentlib.php');
791 list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
793 $errors = environment_get_errors($environment_results);
794 cli_heading(get_string('environment', 'admin'));
795 foreach ($errors as $error) {
796 list($info, $report) = $error;
797 echo "!! $info !!\n$report\n\n";
802 // Test plugin dependencies.
804 if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
805 cli_problem(get_string('pluginscheckfailed', 'admin', array('pluginslist' => implode(', ', array_unique($failed)))));
806 cli_error(get_string('pluginschecktodo', 'admin'));
809 if (!$options['skip-database']) {
810 install_cli_database($options, $interactive);
812 echo get_string('cliskipdatabase', 'install')."\n";
815 echo get_string('cliinstallfinished', 'install')."\n";
816 exit(0); // 0 means success