MDL-57432 lib: unify PHP version checks
[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 // Force OPcache reset if used, we do not want any stale caches
40 // when preparing test environment.
41 if (function_exists('opcache_reset')) {
42     opcache_reset();
43 }
45 $help =
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.
52 Options:
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
79                       problem encountered.
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
87 Example:
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';
94 $distro = null;
95 if (file_exists($distrolibfile)) {
96     require_once($distrolibfile);
97     if (function_exists('distro_get_config')) {
98         $distro = distro_get_config();
99     }
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']) {
110         echo $help;
111         echo "\n\n";
112     }
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     }
121 $olddir = getcwd();
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");
129     exit(1);
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
154 global $CFG;
155 $CFG = new stdClass();
156 $CFG->lang                 = 'en';
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);
197 } else {
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();
205 global $SESSION;
206 global $USER;
208 global $COURSE;
209 $COURSE = new stdClass();
210 $COURSE->id = 1;
212 global $SITE;
213 $SITE = $COURSE;
214 define('SITEID', 1);
216 //Database types
217 $databases = array('mysqli' => moodle_database::get_driver_instance('mysqli', 'native'),
218                    'mariadb'=> moodle_database::get_driver_instance('mariadb', 'native'),
219                    'pgsql'  => moodle_database::get_driver_instance('pgsql',  'native'),
220                    'oci'    => moodle_database::get_driver_instance('oci',    'native'),
221                    'sqlsrv' => moodle_database::get_driver_instance('sqlsrv', 'native'), // MS SQL*Server PHP driver
222                    'mssql'  => moodle_database::get_driver_instance('mssql',  'native'), // FreeTDS driver
223                   );
224 foreach ($databases as $type=>$database) {
225     if ($database->driver_installed() !== true) {
226         unset($databases[$type]);
227     }
229 if (empty($databases)) {
230     $defaultdb = '';
231 } else {
232     reset($databases);
233     $defaultdb = key($databases);
236 // now get cli options
237 list($options, $unrecognized) = cli_get_params(
238     array(
239         'chmod'             => isset($distro->directorypermissions) ? sprintf('%04o',$distro->directorypermissions) : '2777', // let distros set dir permissions
240         'lang'              => $CFG->lang,
241         'wwwroot'           => '',
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
247         'dbpass'            => '',
248         'dbport'            => '',
249         'dbsocket'          => '',
250         'prefix'            => 'mdl_',
251         'fullname'          => '',
252         'shortname'         => '',
253         'summary'           => '',
254         'adminuser'         => 'admin',
255         'adminpass'         => '',
256         'adminemail'        => '',
257         'upgradekey'        => '',
258         'non-interactive'   => false,
259         'agree-license'     => false,
260         'allow-unstable'    => false,
261         'skip-database'     => false,
262         'help'              => false
263     ),
264     array(
265         'h' => 'help'
266     )
267 );
269 $interactive = empty($options['non-interactive']);
271 // set up language
272 $lang = clean_param($options['lang'], PARAM_SAFEDIR);
273 $languages = get_string_manager()->get_list_of_translations();
274 if (array_key_exists($lang, $languages)) {
275     $CFG->lang = $lang;
278 if ($unrecognized) {
279     $unrecognized = implode("\n  ", $unrecognized);
280     cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
283 if ($options['help']) {
284     echo $help;
285     die;
288 //Print header
289 cli_logo();
290 echo PHP_EOL;
291 echo get_string('cliinstallheader', 'install', $CFG->target_release)."\n";
293 //Fist select language
294 if ($interactive) {
295     cli_separator();
296     // Do not put the langs into columns because it is not compatible with RTL.
297     $default = $CFG->lang;
298     cli_heading(get_string('chooselanguagehead', 'install'));
299     if (array_key_exists($default, $languages)) {
300         echo $default.' - '.$languages[$default]."\n";
301     }
302     if ($default !== 'en') {
303         echo 'en - English (en)'."\n";
304     }
305     echo '? - '.get_string('availablelangs', 'install')."\n";
306     $prompt = get_string('clitypevaluedefault', 'admin', $CFG->lang);
307     $error = '';
308     do {
309         echo $error;
310         $input = cli_input($prompt, $default);
312         if ($input === '?') {
313             echo implode("\n", $languages)."\n";
314             $error = "\n";
316         } else {
317             $input = clean_param($input, PARAM_SAFEDIR);
319             if (!array_key_exists($input, $languages)) {
320                 $error = get_string('cliincorrectvalueretry', 'admin')."\n";
321             } else {
322                 $error = '';
323             }
324         }
325     } while ($error !== '');
326     $CFG->lang = $input;
327 } else {
328     // already selected and verified
331 // Set directorypermissions first
332 $chmod = octdec(clean_param($options['chmod'], PARAM_INT));
333 if ($interactive) {
334     cli_separator();
335     cli_heading(get_string('datarootpermission', 'install'));
336     $prompt = get_string('clitypevaluedefault', 'admin', decoct($chmod));
337     $error = '';
338     do {
339         echo $error;
340         $input = cli_input($prompt, decoct($chmod));
341         $input = octdec(clean_param($input, PARAM_INT));
342         if (empty($input)) {
343             $error = get_string('cliincorrectvalueretry', 'admin')."\n";
344         } else {
345             $error = '';
346         }
347     } while ($error !== '');
348     $chmod = $input;
350 } else {
351     if (empty($chmod)) {
352         $a = (object)array('option' => 'chmod', 'value' => decoct($chmod));
353         cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
354     }
356 $CFG->directorypermissions = $chmod;
357 $CFG->filepermissions      = ($CFG->directorypermissions & 0666);
358 $CFG->umaskpermissions     = (($CFG->directorypermissions & 0777) ^ 0777);
360 //We need wwwroot before we test dataroot
361 $wwwroot = clean_param($options['wwwroot'], PARAM_URL);
362 $wwwroot = trim($wwwroot, '/');
363 if ($interactive) {
364     cli_separator();
365     cli_heading(get_string('wwwroot', 'install'));
366     if (strpos($wwwroot, 'http') === 0) {
367         $prompt = get_string('clitypevaluedefault', 'admin', $wwwroot);
368     } else {
369         $wwwroot = null;
370         $prompt = get_string('clitypevalue', 'admin');
371     }
372     $error = '';
373     do {
374         echo $error;
375         $input = cli_input($prompt, $wwwroot);
376         $input = clean_param($input, PARAM_URL);
377         $input = trim($input, '/');
378         if (strpos($input, 'http') !== 0) {
379             $error = get_string('cliincorrectvalueretry', 'admin')."\n";
380         } else {
381             $error = '';
382         }
383     } while ($error !== '');
384     $wwwroot = $input;
386 } else {
387     if (strpos($wwwroot, 'http') !== 0) {
388         $a = (object)array('option'=>'wwwroot', 'value'=>$wwwroot);
389         cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
390     }
392 $CFG->wwwroot       = $wwwroot;
393 $CFG->httpswwwroot  = $CFG->wwwroot;
396 //We need dataroot before lang download
397 $CFG->dataroot = $options['dataroot'];
398 if ($interactive) {
399     cli_separator();
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     }
410     cli_heading(get_string('dataroot', 'install'));
411     $error = '';
412     do {
413         if ($CFG->dataroot !== '') {
414             $prompt = get_string('clitypevaluedefault', 'admin', $CFG->dataroot);
415         } else {
416             $prompt = get_string('clitypevalue', 'admin');
417         }
418         echo $error;
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()) {
423             $CFG->dataroot = '';
424             $error = get_string('pathsunsecuredataroot', 'install')."\n";
425         } else {
426             if (install_init_dataroot($CFG->dataroot, $CFG->directorypermissions)) {
427                 $error = '';
428             } else {
429                 $a = (object)array('dataroot' => $CFG->dataroot);
430                 $error = get_string('pathserrcreatedataroot', 'install', $a)."\n";
431             }
432         }
434     } while ($error !== '');
436 } else {
437     if (is_dataroot_insecure()) {
438         cli_error(get_string('pathsunsecuredataroot', 'install'));
439     }
440     if (!install_init_dataroot($CFG->dataroot, $CFG->directorypermissions)) {
441         $a = (object)array('dataroot' => $CFG->dataroot);
442         cli_error(get_string('pathserrcreatedataroot', 'install', $a));
443     }
445 $CFG->tempdir       = $CFG->dataroot.'/temp';
446 $CFG->cachedir      = $CFG->dataroot.'/cache';
447 $CFG->localcachedir = $CFG->dataroot.'/localcache';
449 // download required lang packs
450 if ($CFG->lang !== 'en') {
451     $installer = new lang_installer($CFG->lang);
452     $results = $installer->run();
453     foreach ($results as $langcode => $langstatus) {
454         if ($langstatus === lang_installer::RESULT_DOWNLOADERROR) {
455             $a       = new stdClass();
456             $a->url  = $installer->lang_pack_url($langcode);
457             $a->dest = $CFG->dataroot.'/lang';
458             cli_problem(get_string('remotedownloaderror', 'error', $a));
459         }
460     }
463 // switch the string_manager instance to stop using install/lang/
464 $CFG->early_install_lang = false;
465 $CFG->langotherroot      = $CFG->dataroot.'/lang';
466 $CFG->langlocalroot      = $CFG->dataroot.'/lang';
467 get_string_manager(true);
469 // make sure we are installing stable release or require a confirmation
470 if (isset($maturity)) {
471     if (($maturity < MATURITY_STABLE) and !$options['allow-unstable']) {
472         $maturitylevel = get_string('maturity'.$maturity, 'admin');
474         if ($interactive) {
475             cli_separator();
476             cli_heading(get_string('notice'));
477             echo get_string('maturitycorewarning', 'admin', $maturitylevel) . PHP_EOL;
478             echo get_string('morehelp') . ': ' . get_docs_url('admin/versions') . PHP_EOL;
479             echo get_string('continue') . PHP_EOL;
480             $prompt = get_string('cliyesnoprompt', 'admin');
481             $input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin')));
482             if ($input == get_string('clianswerno', 'admin')) {
483                 exit(1);
484             }
485         } else {
486             cli_problem(get_string('maturitycorewarning', 'admin', $maturitylevel));
487             cli_error(get_string('maturityallowunstable', 'admin'));
488         }
489     }
492 // ask for db type - show only drivers available
493 if ($interactive) {
494     $options['dbtype'] = strtolower($options['dbtype']);
495     cli_separator();
496     cli_heading(get_string('databasetypehead', 'install'));
497     foreach ($databases as $type=>$database) {
498         echo " $type \n";
499     }
500     if (!empty($databases[$options['dbtype']])) {
501         $prompt = get_string('clitypevaluedefault', 'admin', $options['dbtype']);
502     } else {
503         $prompt = get_string('clitypevalue', 'admin');
504     }
505     $CFG->dbtype = cli_input($prompt, $options['dbtype'], array_keys($databases));
507 } else {
508     if (empty($databases[$options['dbtype']])) {
509         $a = (object)array('option'=>'dbtype', 'value'=>$options['dbtype']);
510         cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
511     }
512     $CFG->dbtype = $options['dbtype'];
514 $database = $databases[$CFG->dbtype];
517 // ask for db host
518 if ($interactive) {
519     cli_separator();
520     cli_heading(get_string('databasehost', 'install'));
521     if ($options['dbhost'] !== '') {
522         $prompt = get_string('clitypevaluedefault', 'admin', $options['dbhost']);
523     } else {
524         $prompt = get_string('clitypevalue', 'admin');
525     }
526     $CFG->dbhost = cli_input($prompt, $options['dbhost']);
528 } else {
529     $CFG->dbhost = $options['dbhost'];
532 // ask for db name
533 if ($interactive) {
534     cli_separator();
535     cli_heading(get_string('databasename', 'install'));
536     if ($options['dbname'] !== '') {
537         $prompt = get_string('clitypevaluedefault', 'admin', $options['dbname']);
538     } else {
539         $prompt = get_string('clitypevalue', 'admin');
540     }
541     $CFG->dbname = cli_input($prompt, $options['dbname']);
543 } else {
544     $CFG->dbname = $options['dbname'];
547 // ask for db prefix
548 if ($interactive) {
549     cli_separator();
550     cli_heading(get_string('dbprefix', 'install'));
551     //TODO: solve somehow the prefix trouble for oci
552     if ($options['prefix'] !== '') {
553         $prompt = get_string('clitypevaluedefault', 'admin', $options['prefix']);
554     } else {
555         $prompt = get_string('clitypevalue', 'admin');
556     }
557     $CFG->prefix = cli_input($prompt, $options['prefix']);
559 } else {
560     $CFG->prefix = $options['prefix'];
563 // ask for db port
564 if ($interactive) {
565     cli_separator();
566     cli_heading(get_string('databaseport', 'install'));
567     $prompt = get_string('clitypevaluedefault', 'admin', $options['dbport']);
568     $CFG->dboptions['dbport'] = (int)cli_input($prompt, $options['dbport']);
570 } else {
571     $CFG->dboptions['dbport'] = (int)$options['dbport'];
573 if ($CFG->dboptions['dbport'] <= 0) {
574     $CFG->dboptions['dbport'] = '';
577 // ask for db socket
578 if ($CFG->ostype === 'WINDOWS') {
579     $CFG->dboptions['dbsocket'] = '';
581 } else if ($interactive and empty($CFG->dboptions['dbport'])) {
582     cli_separator();
583     cli_heading(get_string('databasesocket', 'install'));
584     $prompt = get_string('clitypevaluedefault', 'admin', $options['dbsocket']);
585     $CFG->dboptions['dbsocket'] = cli_input($prompt, $options['dbsocket']);
587 } else {
588     $CFG->dboptions['dbsocket'] = $options['dbsocket'];
591 // ask for db user
592 if ($interactive) {
593     cli_separator();
594     cli_heading(get_string('databaseuser', 'install'));
595     if ($options['dbuser'] !== '') {
596         $prompt = get_string('clitypevaluedefault', 'admin', $options['dbuser']);
597     } else {
598         $prompt = get_string('clitypevalue', 'admin');
599     }
600     $CFG->dbuser = cli_input($prompt, $options['dbuser']);
602 } else {
603     $CFG->dbuser = $options['dbuser'];
606 // ask for db password
607 if ($interactive) {
608     cli_separator();
609     cli_heading(get_string('databasepass', 'install'));
610     do {
611         if ($options['dbpass'] !== '') {
612             $prompt = get_string('clitypevaluedefault', 'admin', $options['dbpass']);
613         } else {
614             $prompt = get_string('clitypevalue', 'admin');
615         }
617         $CFG->dbpass = cli_input($prompt, $options['dbpass']);
618         if (function_exists('distro_pre_create_db')) { // Hook for distros needing to do something before DB creation
619             $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);
620         }
621         $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']));
622     } while ($hint_database !== '');
624 } else {
625     $CFG->dbpass = $options['dbpass'];
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     if ($hint_database !== '') {
628         cli_error(get_string('dbconnectionerror', 'install'));
629     }
632 // ask for fullname
633 if ($interactive) {
634     cli_separator();
635     cli_heading(get_string('fullsitename', 'moodle'));
637     if ($options['fullname'] !== '') {
638         $prompt = get_string('clitypevaluedefault', 'admin', $options['fullname']);
639     } else {
640         $prompt = get_string('clitypevalue', 'admin');
641     }
643     do {
644         $options['fullname'] = cli_input($prompt, $options['fullname']);
645     } while (empty($options['fullname']));
646 } else {
647     if (empty($options['fullname'])) {
648         $a = (object)array('option'=>'fullname', 'value'=>$options['fullname']);
649         cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
650     }
653 // ask for shortname
654 if ($interactive) {
655     cli_separator();
656     cli_heading(get_string('shortsitename', 'moodle'));
658     if ($options['shortname'] !== '') {
659         $prompt = get_string('clitypevaluedefault', 'admin', $options['shortname']);
660     } else {
661         $prompt = get_string('clitypevalue', 'admin');
662     }
664     do {
665         $options['shortname'] = cli_input($prompt, $options['shortname']);
666     } while (empty($options['shortname']));
667 } else {
668     if (empty($options['shortname'])) {
669         $a = (object)array('option'=>'shortname', 'value'=>$options['shortname']);
670         cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
671     }
674 // ask for admin user name
675 if ($interactive) {
676     cli_separator();
677     cli_heading(get_string('cliadminusername', 'install'));
678     if (!empty($options['adminuser'])) {
679         $prompt = get_string('clitypevaluedefault', 'admin', $options['adminuser']);
680     } else {
681         $prompt = get_string('clitypevalue', 'admin');
682     }
683     do {
684         $options['adminuser'] = cli_input($prompt, $options['adminuser']);
685     } while (empty($options['adminuser']) or $options['adminuser'] === 'guest');
686 } else {
687     if (empty($options['adminuser']) or $options['adminuser'] === 'guest') {
688         $a = (object)array('option'=>'adminuser', 'value'=>$options['adminuser']);
689         cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
690     }
693 // ask for admin user password
694 if ($interactive) {
695     cli_separator();
696     cli_heading(get_string('cliadminpassword', 'install'));
697     $prompt = get_string('clitypevalue', 'admin');
698     do {
699         $options['adminpass'] = cli_input($prompt);
700     } while (empty($options['adminpass']) or $options['adminpass'] === 'admin');
701 } else {
702     if (empty($options['adminpass']) or $options['adminpass'] === 'admin') {
703         $a = (object)array('option'=>'adminpass', 'value'=>$options['adminpass']);
704         cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
705     }
708 // Ask for the admin email address.
709 if ($interactive) {
710     cli_separator();
711     cli_heading(get_string('cliadminemail', 'install'));
712     $prompt = get_string('clitypevaluedefault', 'admin', $options['adminemail']);
713     $options['adminemail'] = cli_input($prompt);
716 // Validate that the address provided was an e-mail address.
717 if (!empty($options['adminemail']) && !validate_email($options['adminemail'])) {
718     $a = (object) array('option' => 'adminemail', 'value' => $options['adminemail']);
719     cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
722 // Ask for the upgrade key.
723 if ($interactive) {
724     cli_separator();
725     cli_heading(get_string('upgradekeyset', 'admin'));
726     if ($options['upgradekey'] !== '') {
727         $prompt = get_string('clitypevaluedefault', 'admin', $options['upgradekey']);
728         $options['upgradekey'] = cli_input($prompt, $options['upgradekey']);
729     } else {
730         $prompt = get_string('clitypevalue', 'admin');
731         $options['upgradekey'] = cli_input($prompt);
732     }
735 // Set the upgrade key if it was provided.
736 if ($options['upgradekey'] !== '') {
737     $CFG->upgradekey = $options['upgradekey'];
740 if ($interactive) {
741     if (!$options['agree-license']) {
742         cli_separator();
743         cli_heading(get_string('copyrightnotice'));
744         echo "Moodle  - Modular Object-Oriented Dynamic Learning Environment\n";
745         echo get_string('gpl3')."\n\n";
746         echo get_string('doyouagree')."\n";
747         $prompt = get_string('cliyesnoprompt', 'admin');
748         $input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin')));
749         if ($input == get_string('clianswerno', 'admin')) {
750             exit(1);
751         }
752     }
753 } else {
754     if (!$options['agree-license']) {
755         cli_error(get_string('climustagreelicense', 'install'));
756     }
759 // Finally we have all info needed for config.php
760 $configphp = install_generate_configphp($database, $CFG);
761 umask(0137);
762 if (($fh = fopen($configfile, 'w')) !== false) {
763     fwrite($fh, $configphp);
764     fclose($fh);
767 if (!file_exists($configfile)) {
768     cli_error('Can not create config file.');
771 // remember selected language
772 $installlang = $CFG->lang;
773 // return back to original dir before executing setup.php which changes the dir again
774 chdir($olddir);
775 // We have config.php, it is a real php script from now on :-)
776 require($configfile);
778 // use selected language
779 $CFG->lang = $installlang;
780 $SESSION->lang = $CFG->lang;
782 require("$CFG->dirroot/version.php");
784 // Test environment first.
785 require_once($CFG->libdir . '/environmentlib.php');
786 list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
787 if (!$envstatus) {
788     $errors = environment_get_errors($environment_results);
789     cli_heading(get_string('environment', 'admin'));
790     foreach ($errors as $error) {
791         list($info, $report) = $error;
792         echo "!! $info !!\n$report\n\n";
793     }
794     exit(1);
797 // Test plugin dependencies.
798 $failed = array();
799 if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
800     cli_problem(get_string('pluginscheckfailed', 'admin', array('pluginslist' => implode(', ', array_unique($failed)))));
801     cli_error(get_string('pluginschecktodo', 'admin'));
804 if (!$options['skip-database']) {
805     install_cli_database($options, $interactive);
806 } else {
807     echo get_string('cliskipdatabase', 'install')."\n";
810 echo get_string('cliinstallfinished', 'install')."\n";
811 exit(0); // 0 means success