38aa06e87d21e5db3258aa671be95f647df21e60
[moodle.git] / admin / cli / install.php
1 <?php
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/>.
18 /**
19  * This script creates config.php file and prepares database.
20  *
21  * This script is not intended for beginners!
22  * Potential problems:
23  * - su to apache account or sudo before execution
24  * - not compatible with Windows platform
25  *
26  * @package    core
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  */
32 define('CLI_SCRIPT', true);
34 // extra execution prevention - we can not just require config.php here
35 if (isset($_SERVER['REMOTE_ADDR'])) {
36     exit(1);
37 }
39 $help =
40 "Command line Moodle installer, creates config.php and initializes database.
41 Please note you must execute this script with the same uid as apache
42 or use chmod/chown after installation.
44 Site defaults may be changed via local/defaults.php.
46 Options:
47 --chmod=OCTAL-MODE    Permissions of new directories created within dataroot.
48                       Default is 2777. You may want to change it to 2770
49                       or 2750 or 750. See chmod man page for details.
50 --lang=CODE           Installation and default site language.
51 --wwwroot=URL         Web address for the Moodle site,
52                       required in non-interactive mode.
53 --dataroot=DIR        Location of the moodle data folder,
54                       must not be web accessible. Default is moodledata
55                       in the parent directory.
56 --dbtype=TYPE         Database type. Default is mysqli
57 --dbhost=HOST         Database host. Default is localhost
58 --dbname=NAME         Database name. Default is moodle
59 --dbuser=USERNAME     Database user. Default is root
60 --dbpass=PASSWORD     Database password. Default is blank
61 --dbsocket            Use database sockets. Available for some databases only.
62 --prefix=STRING       Table prefix for above database tables. Default is mdl_
63 --fullname=STRING     The fullname of the site
64 --shortname=STRING    The shortname of the site
65 --adminuser=USERNAME  Username for the moodle admin account. Default is admin
66 --adminpass=PASSWORD  Password for the moodle admin account,
67                       required in non-interactive mode.
68 --non-interactive     No interactive questions, installation fails if any
69                       problem encountered.
70 --agree-license       Indicates agreement with software license,
71                       required in non-interactive mode.
72 --allow-unstable      Install even if the version is not marked as stable yet,
73                       required in non-interactive mode.
74 -h, --help            Print out this help
76 Example:
77 \$sudo -u www-data /usr/bin/php admin/cli/install.php --lang=cs
78 "; //TODO: localize, mark as needed in install - to be translated later when everything is finished
81 // distro specific customisation
82 $distrolibfile = dirname(dirname(dirname(__FILE__))).'/install/distrolib.php';
83 $distro = null;
84 if (file_exists($distrolibfile)) {
85     require_once($distrolibfile);
86     if (function_exists('distro_get_config')) {
87         $distro = distro_get_config();
88     }
89 }
91 // Nothing to do if config.php exists
92 $configfile = dirname(dirname(dirname(__FILE__))).'/config.php';
93 if (file_exists($configfile)) {
94     require($configfile);
95     require_once($CFG->libdir.'/clilib.php');
96     list($options, $unrecognized) = cli_get_params(array('help'=>false), array('h'=>'help'));
98     if ($options['help']) {
99         echo $help;
100         echo "\n\n";
101     }
103     if ($DB->get_manager()->table_exists('config')) {
104         cli_error(get_string('clialreadyinstalled', 'install'));
105     } else {
106         cli_error(get_string('clialreadyconfigured', 'install'));
107     }
110 $olddir = getcwd();
112 // change directory so that includes below work properly
113 chdir(dirname($_SERVER['argv'][0]));
115 // Servers should define a default timezone in php.ini, but if they don't then make sure something is defined.
116 // This is a quick hack.  Ideally we should ask the admin for a value.  See MDL-22625 for more on this.
117 if (function_exists('date_default_timezone_set') and function_exists('date_default_timezone_get')) {
118     @date_default_timezone_set(@date_default_timezone_get());
121 // make sure PHP errors are displayed - helps with diagnosing of problems
122 @error_reporting(E_ALL);
123 @ini_set('display_errors', '1');
124 // we need a lot of memory
125 @ini_set('memory_limit', '128M');
127 /** Used by library scripts to check they are being called by Moodle */
128 define('MOODLE_INTERNAL', true);
130 // Check that PHP is of a sufficient version
131 if (version_compare(phpversion(), "5.3.2") < 0) {
132     $phpversion = phpversion();
133     // do NOT localise - lang strings would not work here and we CAN NOT move it after installib
134     fwrite(STDERR, "Moodle 2.1 or later requires at least PHP 5.3.2 (currently using version $phpversion).\n");
135     fwrite(STDERR, "Please upgrade your server software or install older Moodle version.\n");
136     exit(1);
139 // set up configuration
140 $CFG = new stdClass();
141 $CFG->lang                 = 'en';
142 $CFG->dirroot              = dirname(dirname(dirname(__FILE__)));
143 $CFG->libdir               = "$CFG->dirroot/lib";
144 $CFG->wwwroot              = "http://localhost";
145 $CFG->httpswwwroot         = $CFG->wwwroot;
146 $CFG->docroot              = 'http://docs.moodle.org';
147 $CFG->running_installer    = true;
148 $CFG->early_install_lang   = true;
150 $parts = explode('/', str_replace('\\', '/', dirname(dirname(__FILE__))));
151 $CFG->admin                = array_pop($parts);
153 //point pear include path to moodles lib/pear so that includes and requires will search there for files before anywhere else
154 //the problem is that we need specific version of quickforms and hacked excel files :-(
155 ini_set('include_path', $CFG->libdir.'/pear' . PATH_SEPARATOR . ini_get('include_path'));
157 require_once($CFG->libdir.'/installlib.php');
158 require_once($CFG->libdir.'/clilib.php');
159 require_once($CFG->libdir.'/setuplib.php');
160 require_once($CFG->libdir.'/textlib.class.php');
161 require_once($CFG->libdir.'/weblib.php');
162 require_once($CFG->libdir.'/dmllib.php');
163 require_once($CFG->libdir.'/moodlelib.php');
164 require_once($CFG->libdir.'/deprecatedlib.php');
165 require_once($CFG->libdir.'/adminlib.php');
166 require_once($CFG->libdir.'/componentlib.class.php');
168 require($CFG->dirroot.'/version.php');
169 $CFG->target_release = $release;
171 //Database types
172 $databases = array('mysqli' => moodle_database::get_driver_instance('mysqli', 'native'),
173                    'pgsql'  => moodle_database::get_driver_instance('pgsql',  'native'),
174                    'oci'    => moodle_database::get_driver_instance('oci',    'native'),
175                    'sqlsrv' => moodle_database::get_driver_instance('sqlsrv', 'native'), // MS SQL*Server PHP driver
176                    'mssql'  => moodle_database::get_driver_instance('mssql',  'native'), // FreeTDS driver
177                   );
178 foreach ($databases as $type=>$database) {
179     if ($database->driver_installed() !== true) {
180         unset($databases[$type]);
181     }
183 if (empty($databases)) {
184     $defaultdb = '';
185 } else {
186     reset($databases);
187     $defaultdb = key($databases);
190 // now get cli options
191 list($options, $unrecognized) = cli_get_params(
192     array(
193         'chmod'             => isset($distro->directorypermissions) ? sprintf('%04o',$distro->directorypermissions) : '2777', // let distros set dir permissions
194         'lang'              => $CFG->lang,
195         'wwwroot'           => '',
196         'dataroot'          => empty($distro->dataroot) ? str_replace('\\', '/', dirname(dirname(dirname(dirname(__FILE__)))).'/moodledata'): $distro->dataroot, // initialised later after including libs or by distro
197         'dbtype'            => empty($distro->dbtype) ? $defaultdb : $distro->dbtype, // let distro skip dbtype selection
198         'dbhost'            => empty($distro->dbhost) ? 'localhost' : $distro->dbhost, // let distros set dbhost
199         'dbname'            => 'moodle',
200         'dbuser'            => empty($distro->dbuser) ? 'root' : $distro->dbuser, // let distros set dbuser
201         'dbpass'            => '',
202         'dbsocket'          => false,
203         'prefix'            => 'mdl_',
204         'fullname'          => '',
205         'shortname'         => '',
206         'adminuser'         => 'admin',
207         'adminpass'         => '',
208         'non-interactive'   => false,
209         'agree-license'     => false,
210         'allow-unstable'    => false,
211         'help'              => false
212     ),
213     array(
214         'h' => 'help'
215     )
216 );
218 $interactive = empty($options['non-interactive']);
220 // set up language
221 $lang = clean_param($options['lang'], PARAM_SAFEDIR);
222 if (file_exists($CFG->dirroot.'/install/lang/'.$lang)) {
223     $CFG->lang = $lang;
226 if ($unrecognized) {
227     $unrecognized = implode("\n  ", $unrecognized);
228     cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
231 if ($options['help']) {
232     echo $help;
233     die;
236 //Print header
237 echo get_string('cliinstallheader', 'install', $CFG->target_release)."\n";
239 //Fist select language
240 if ($interactive) {
241     cli_separator();
242     $languages = get_string_manager()->get_list_of_translations();
243     // Do not put the langs into columns because it is not compatible with RTL.
244     $langlist = implode("\n", $languages);
245     $default = $CFG->lang;
246     cli_heading(get_string('availablelangs', 'install'));
247     echo $langlist."\n";
248     $prompt = get_string('clitypevaluedefault', 'admin', $CFG->lang);
249     $error = '';
250     do {
251         echo $error;
252         $input = cli_input($prompt, $default);
253         $input = clean_param($input, PARAM_SAFEDIR);
255         if (!file_exists($CFG->dirroot.'/install/lang/'.$input)) {
256             $error = get_string('cliincorrectvalueretry', 'admin')."\n";
257         } else {
258             $error = '';
259         }
260     } while ($error !== '');
261     $CFG->lang = $input;
262 } else {
263     // already selected and verified
266 // Set directorypermissions first
267 $chmod = octdec(clean_param($options['chmod'], PARAM_INT));
268 if ($interactive) {
269     cli_separator();
270     cli_heading(get_string('datarootpermission', 'install'));
271     $prompt = get_string('clitypevaluedefault', 'admin', decoct($chmod));
272     $error = '';
273     do {
274         echo $error;
275         $input = cli_input($prompt, decoct($chmod));
276         $input = octdec(clean_param($input, PARAM_INT));
277         if (empty($input)) {
278             $error = get_string('cliincorrectvalueretry', 'admin')."\n";
279         } else {
280             $error = '';
281         }
282     } while ($error !== '');
283     $chmod = $input;
285 } else {
286     if (empty($chmod)) {
287         $a = (object)array('option' => 'chmod', 'value' => decoct($chmod));
288         cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
289     }
291 $CFG->directorypermissions = $chmod;
293 //We need wwwroot before we test dataroot
294 $wwwroot = clean_param($options['wwwroot'], PARAM_URL);
295 $wwwroot = trim($wwwroot, '/');
296 if ($interactive) {
297     cli_separator();
298     cli_heading(get_string('wwwroot', 'install'));
299     if (strpos($wwwroot, 'http') === 0) {
300         $prompt = get_string('clitypevaluedefault', 'admin', $wwwroot);
301     } else {
302         $wwwroot = null;
303         $prompt = get_string('clitypevalue', 'admin');
304     }
305     $error = '';
306     do {
307         echo $error;
308         $input = cli_input($prompt, $wwwroot);
309         $input = clean_param($input, PARAM_URL);
310         $input = trim($input, '/');
311         if (strpos($input, 'http') !== 0) {
312             $error = get_string('cliincorrectvalueretry', 'admin')."\n";
313         } else {
314             $error = '';
315         }
316     } while ($error !== '');
317     $wwwroot = $input;
319 } else {
320     if (strpos($wwwroot, 'http') !== 0) {
321         $a = (object)array('option'=>'wwwroot', 'value'=>$wwwroot);
322         cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
323     }
325 $CFG->wwwroot       = $wwwroot;
326 $CFG->httpswwwroot  = $CFG->wwwroot;
329 //We need dataroot before lang download
330 $CFG->dataroot = $options['dataroot'];
331 if ($interactive) {
332     cli_separator();
333     $i=0;
334     while(is_dataroot_insecure()) {
335         $parrent = dirname($CFG->dataroot);
336         $i++;
337         if ($parrent == '/' or $parrent == '.' or preg_match('/^[a-z]:\\\?$/i', $parrent) or ($i > 100)) {
338             $CFG->dataroot = ''; //can not find secure location for dataroot
339             break;
340         }
341         $CFG->dataroot = dirname($parrent).'/moodledata';
342     }
343     cli_heading(get_string('dataroot', 'install'));
344     $error = '';
345     do {
346         if ($CFG->dataroot !== '') {
347             $prompt = get_string('clitypevaluedefault', 'admin', $CFG->dataroot);
348         } else {
349             $prompt = get_string('clitypevalue', 'admin');
350         }
351         echo $error;
352         $CFG->dataroot = cli_input($prompt, $CFG->dataroot);
353         if ($CFG->dataroot === '') {
354             $error = get_string('cliincorrectvalueretry', 'admin')."\n";
355         } else if (is_dataroot_insecure()) {
356             $CFG->dataroot = '';
357             $error = get_string('pathsunsecuredataroot', 'install')."\n";
358         } else {
359             if (install_init_dataroot($CFG->dataroot, $CFG->directorypermissions)) {
360                 $error = '';
361             } else {
362                 $a = (object)array('dataroot' => $CFG->dataroot);
363                 $error = get_string('pathserrcreatedataroot', 'install', $a)."\n";
364             }
365         }
367     } while ($error !== '');
369 } else {
370     if (is_dataroot_insecure()) {
371         cli_error(get_string('pathsunsecuredataroot', 'install'));
372     }
373     if (!install_init_dataroot($CFG->dataroot, $CFG->directorypermissions)) {
374         $a = (object)array('dataroot' => $CFG->dataroot);
375         cli_error(get_string('pathserrcreatedataroot', 'install', $a));
376     }
378 $CFG->tempdir  = $CFG->dataroot.'/temp';
379 $CFG->cachedir = $CFG->dataroot.'/cache';
381 // download required lang packs
382 if ($CFG->lang !== 'en') {
383     $installer = new lang_installer($CFG->lang);
384     $results = $installer->run();
385     foreach ($results as $langcode => $langstatus) {
386         if ($langstatus === lang_installer::RESULT_DOWNLOADERROR) {
387             $a       = new stdClass();
388             $a->url  = $installer->lang_pack_url($langcode);
389             $a->dest = $CFG->dataroot.'/lang';
390             cli_problem(get_string('remotedownloaderror', 'error', $a));
391         }
392     }
395 // switch the string_manager instance to stop using install/lang/
396 $CFG->early_install_lang = false;
397 $CFG->langotherroot      = $CFG->dataroot.'/lang';
398 $CFG->langlocalroot      = $CFG->dataroot.'/lang';
399 get_string_manager(true);
401 // make sure we are installing stable release or require a confirmation
402 if (isset($maturity)) {
403     if (($maturity < MATURITY_STABLE) and !$options['allow-unstable']) {
404         $maturitylevel = get_string('maturity'.$maturity, 'admin');
406         if ($interactive) {
407             cli_separator();
408             cli_heading(get_string('notice'));
409             echo get_string('maturitycorewarning', 'admin', $maturitylevel) . PHP_EOL;
410             echo get_string('morehelp') . ': ' . get_docs_url('admin/versions') . PHP_EOL;
411             echo get_string('continue') . PHP_EOL;
412             $prompt = get_string('cliyesnoprompt', 'admin');
413             $input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin')));
414             if ($input == get_string('clianswerno', 'admin')) {
415                 exit(1);
416             }
417         } else {
418             cli_problem(get_string('maturitycorewarning', 'admin', $maturitylevel));
419             cli_error(get_string('maturityallowunstable', 'admin'));
420         }
421     }
424 // ask for db type - show only drivers available
425 if ($interactive) {
426     $options['dbtype'] = strtolower($options['dbtype']);
427     cli_separator();
428     cli_heading(get_string('databasetypehead', 'install'));
429     foreach ($databases as $type=>$database) {
430         echo " $type \n";
431     }
432     if (!empty($databases[$options['dbtype']])) {
433         $prompt = get_string('clitypevaluedefault', 'admin', $options['dbtype']);
434     } else {
435         $prompt = get_string('clitypevalue', 'admin');
436     }
437     $CFG->dbtype = cli_input($prompt, $options['dbtype'], array_keys($databases));
439 } else {
440     if (empty($databases[$options['dbtype']])) {
441         $a = (object)array('option'=>'dbtype', 'value'=>$options['dbtype']);
442         cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
443     }
444     $CFG->dbtype = $options['dbtype'];
446 $database = $databases[$CFG->dbtype];
449 // ask for db host
450 if ($interactive) {
451     cli_separator();
452     cli_heading(get_string('databasehost', 'install'));
453     if ($options['dbhost'] !== '') {
454         $prompt = get_string('clitypevaluedefault', 'admin', $options['dbhost']);
455     } else {
456         $prompt = get_string('clitypevalue', 'admin');
457     }
458     $CFG->dbhost = cli_input($prompt, $options['dbhost']);
460 } else {
461     $CFG->dbhost = $options['dbhost'];
464 // ask for db name
465 if ($interactive) {
466     cli_separator();
467     cli_heading(get_string('databasename', 'install'));
468     if ($options['dbname'] !== '') {
469         $prompt = get_string('clitypevaluedefault', 'admin', $options['dbname']);
470     } else {
471         $prompt = get_string('clitypevalue', 'admin');
472     }
473     $CFG->dbname = cli_input($prompt, $options['dbname']);
475 } else {
476     $CFG->dbname = $options['dbname'];
479 // ask for db prefix
480 if ($interactive) {
481     cli_separator();
482     cli_heading(get_string('dbprefix', 'install'));
483     //TODO: solve somehow the prefix trouble for oci
484     if ($options['prefix'] !== '') {
485         $prompt = get_string('clitypevaluedefault', 'admin', $options['prefix']);
486     } else {
487         $prompt = get_string('clitypevalue', 'admin');
488     }
489     $CFG->prefix = cli_input($prompt, $options['prefix']);
491 } else {
492     $CFG->prefix = $options['prefix'];
495 // ask for db user
496 if ($interactive) {
497     cli_separator();
498     cli_heading(get_string('databaseuser', 'install'));
499     if ($options['dbuser'] !== '') {
500         $prompt = get_string('clitypevaluedefault', 'admin', $options['dbuser']);
501     } else {
502         $prompt = get_string('clitypevalue', 'admin');
503     }
504     $CFG->dbuser = cli_input($prompt, $options['dbuser']);
506 } else {
507     $CFG->dbuser = $options['dbuser'];
510 // ask for db password
511 if ($interactive) {
512     cli_separator();
513     cli_heading(get_string('databasepass', 'install'));
514     do {
515         if ($options['dbpass'] !== '') {
516             $prompt = get_string('clitypevaluedefault', 'admin', $options['dbpass']);
517         } else {
518             $prompt = get_string('clitypevalue', 'admin');
519         }
521         $CFG->dbpass = cli_input($prompt, $options['dbpass']);
522         if (function_exists('distro_pre_create_db')) { // Hook for distros needing to do something before DB creation
523             $distro = distro_pre_create_db($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, array('dbpersist'=>0, 'dbsocket'=>$options['dbsocket']), $distro);
524         }
525         $hint_database = install_db_validate($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, array('dbpersist'=>0, 'dbsocket'=>$options['dbsocket']));
526     } while ($hint_database !== '');
528 } else {
529     $CFG->dbpass = $options['dbpass'];
530     $hint_database = install_db_validate($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, array('dbpersist'=>0, 'dbsocket'=>$options['dbsocket']));
531     if ($hint_database !== '') {
532         cli_error(get_string('dbconnectionerror', 'install'));
533     }
536 // ask for fullname
537 if ($interactive) {
538     cli_separator();
539     cli_heading(get_string('fullsitename', 'moodle'));
541     if ($options['fullname'] !== '') {
542         $prompt = get_string('clitypevaluedefault', 'admin', $options['fullname']);
543     } else {
544         $prompt = get_string('clitypevalue', 'admin');
545     }
547     do {
548         $options['fullname'] = cli_input($prompt, $options['fullname']);
549     } while (empty($options['fullname']));
550 } else {
551     if (empty($options['fullname'])) {
552         $a = (object)array('option'=>'fullname', 'value'=>$options['fullname']);
553         cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
554     }
557 // ask for shortname
558 if ($interactive) {
559     cli_separator();
560     cli_heading(get_string('shortsitename', 'moodle'));
562     if ($options['shortname'] !== '') {
563         $prompt = get_string('clitypevaluedefault', 'admin', $options['shortname']);
564     } else {
565         $prompt = get_string('clitypevalue', 'admin');
566     }
568     do {
569         $options['shortname'] = cli_input($prompt, $options['shortname']);
570     } while (empty($options['shortname']));
571 } else {
572     if (empty($options['shortname'])) {
573         $a = (object)array('option'=>'shortname', 'value'=>$options['shortname']);
574         cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
575     }
578 // ask for admin user name
579 if ($interactive) {
580     cli_separator();
581     cli_heading(get_string('cliadminusername', 'install'));
582     if (!empty($options['adminuser'])) {
583         $prompt = get_string('clitypevaluedefault', 'admin', $options['adminuser']);
584     } else {
585         $prompt = get_string('clitypevalue', 'admin');
586     }
587     do {
588         $options['adminuser'] = cli_input($prompt, $options['adminuser']);
589     } while (empty($options['adminuser']) or $options['adminuser'] === 'guest');
590 } else {
591     if (empty($options['adminuser']) or $options['adminuser'] === 'guest') {
592         $a = (object)array('option'=>'adminuser', 'value'=>$options['adminuser']);
593         cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
594     }
597 // ask for admin user password
598 if ($interactive) {
599     cli_separator();
600     cli_heading(get_string('cliadminpassword', 'install'));
601     $prompt = get_string('clitypevalue', 'admin');
602     do {
603         $options['adminpass'] = cli_input($prompt);
604     } while (empty($options['adminpass']) or $options['adminpass'] === 'admin');
605 } else {
606     if (empty($options['adminpass']) or $options['adminpass'] === 'admin') {
607         $a = (object)array('option'=>'adminpass', 'value'=>$options['adminpass']);
608         cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
609     }
612 if ($interactive) {
613     if (!$options['agree-license']) {
614         cli_separator();
615         cli_heading(get_string('copyrightnotice'));
616         echo "Moodle  - Modular Object-Oriented Dynamic Learning Environment\n";
617         echo get_string('gpl3')."\n\n";
618         echo get_string('doyouagree')."\n";
619         $prompt = get_string('cliyesnoprompt', 'admin');
620         $input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin')));
621         if ($input == get_string('clianswerno', 'admin')) {
622             exit(1);
623         }
624     }
625 } else {
626     if (!$options['agree-license']) {
627         cli_error(get_string('climustagreelicense', 'install'));
628     }
631 // Finally we have all info needed for config.php
632 $configphp = install_generate_configphp($database, $CFG);
633 umask(0137);
634 if (($fh = fopen($configfile, 'w')) !== false) {
635     fwrite($fh, $configphp);
636     fclose($fh);
639 if (!file_exists($configfile)) {
640     cli_error('Can not create config file.');
643 // remember selected language
644 $installlang = $CFG->lang;
645 // return back to original dir before executing setup.php which changes the dir again
646 chdir($olddir);
647 // We have config.php, it is a real php script from now on :-)
648 require($configfile);
650 // use selected language
651 $CFG->lang = $installlang;
652 $SESSION->lang = $CFG->lang;
654 require("$CFG->dirroot/version.php");
656 // Test environment first.
657 require_once($CFG->libdir . '/environmentlib.php');
658 list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
659 if (!$envstatus) {
660     $errors = environment_get_errors($environment_results);
661     cli_heading(get_string('environment', 'admin'));
662     foreach ($errors as $error) {
663         list($info, $report) = $error;
664         echo "!! $info !!\n$report\n\n";
665     }
666     exit(1);
669 // Test plugin dependencies.
670 require_once($CFG->libdir . '/pluginlib.php');
671 $failed = array();
672 if (!plugin_manager::instance()->all_plugins_ok($version, $failed)) {
673     cli_problem(get_string('pluginscheckfailed', 'admin', array('pluginslist' => implode(', ', array_unique($failed)))));
674     cli_error(get_string('pluginschecktodo', 'admin'));
677 install_cli_database($options, $interactive);
679 echo get_string('cliinstallfinished', 'install')."\n";
680 exit(0); // 0 means success