install.php 27.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php

// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * This script creates config.php file and prepares database.
 *
 * This script is not intended for beginners!
 * Potential problems:
 * - su to apache account or sudo before execution
 * - not compatible with Windows platform
 *
26
 * @package    core
27
28
29
30
31
 * @subpackage cli
 * @copyright  2009 Petr Skoda (http://skodak.org)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

32
33
34
define('CLI_SCRIPT', true);

// extra execution prevention - we can not just require config.php here
35
if (isset($_SERVER['REMOTE_ADDR'])) {
36
    exit(1);
37
38
}

39
40
41
42
43
44
// Force OPcache reset if used, we do not want any stale caches
// when preparing test environment.
if (function_exists('opcache_reset')) {
    opcache_reset();
}

45
46
47
48
49
50
51
52
$help =
"Command line Moodle installer, creates config.php and initializes database.
Please note you must execute this script with the same uid as apache
or use chmod/chown after installation.

Site defaults may be changed via local/defaults.php.

Options:
53
54
55
--chmod=OCTAL-MODE    Permissions of new directories created within dataroot.
                      Default is 2777. You may want to change it to 2770
                      or 2750 or 750. See chmod man page for details.
56
57
58
59
--lang=CODE           Installation and default site language.
--wwwroot=URL         Web address for the Moodle site,
                      required in non-interactive mode.
--dataroot=DIR        Location of the moodle data folder,
60
61
                      must not be web accessible. Default is moodledata
                      in the parent directory.
62
63
64
65
66
--dbtype=TYPE         Database type. Default is mysqli
--dbhost=HOST         Database host. Default is localhost
--dbname=NAME         Database name. Default is moodle
--dbuser=USERNAME     Database user. Default is root
--dbpass=PASSWORD     Database password. Default is blank
67
68
--dbport=NUMBER       Use database port.
--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
71
--fullname=STRING     The fullname of the site
--shortname=STRING    The shortname of the site
72
73
--adminuser=USERNAME  Username for the moodle admin account. Default is admin
--adminpass=PASSWORD  Password for the moodle admin account,
74
                      required in non-interactive mode.
75
--adminemail=STRING   Email address for the moodle admin account.
76
77
--non-interactive     No interactive questions, installation fails if any
                      problem encountered.
78
--agree-license       Indicates agreement with software license,
79
                      required in non-interactive mode.
80
81
--allow-unstable      Install even if the version is not marked as stable yet,
                      required in non-interactive mode.
82
83
-h, --help            Print out this help

84
85
Example:
\$sudo -u www-data /usr/bin/php admin/cli/install.php --lang=cs
86
"; //TODO: localize, mark as needed in install - to be translated later when everything is finished
87
88


89
90
91
92
93
94
95
96
97
98
// distro specific customisation
$distrolibfile = dirname(dirname(dirname(__FILE__))).'/install/distrolib.php';
$distro = null;
if (file_exists($distrolibfile)) {
    require_once($distrolibfile);
    if (function_exists('distro_get_config')) {
        $distro = distro_get_config();
    }
}

99
100
101
// Nothing to do if config.php exists
$configfile = dirname(dirname(dirname(__FILE__))).'/config.php';
if (file_exists($configfile)) {
102
    require($configfile);
103
104
105
106
107
108
109
110
    require_once($CFG->libdir.'/clilib.php');
    list($options, $unrecognized) = cli_get_params(array('help'=>false), array('h'=>'help'));

    if ($options['help']) {
        echo $help;
        echo "\n\n";
    }

111
112
113
114
115
    if ($DB->get_manager()->table_exists('config')) {
        cli_error(get_string('clialreadyinstalled', 'install'));
    } else {
        cli_error(get_string('clialreadyconfigured', 'install'));
    }
116
117
}

118
119
$olddir = getcwd();

120
// change directory so that includes below work properly
121
122
chdir(dirname($_SERVER['argv'][0]));

123
// Servers should define a default timezone in php.ini, but if they don't then make sure something is defined.
124
125
126
if (!function_exists('date_default_timezone_set') or !function_exists('date_default_timezone_get')) {
    fwrite(STDERR, "Timezone functions are not available.\n");
    exit(1);
127
}
128
date_default_timezone_set(@date_default_timezone_get());
129

130
131
132
133
134
135
// make sure PHP errors are displayed - helps with diagnosing of problems
@error_reporting(E_ALL);
@ini_set('display_errors', '1');
// we need a lot of memory
@ini_set('memory_limit', '128M');

136
137
138
/** Used by library scripts to check they are being called by Moodle */
define('MOODLE_INTERNAL', true);

139
// Disables all caching.
140
141
define('CACHE_DISABLE_ALL', true);

142
143
define('PHPUNIT_TEST', false);

144
145
define('IGNORE_COMPONENT_CACHE', true);

146
// Check that PHP is of a sufficient version
147
if (version_compare(phpversion(), "5.4.4") < 0) {
148
149
    $phpversion = phpversion();
    // do NOT localise - lang strings would not work here and we CAN NOT move it after installib
150
    fwrite(STDERR, "Moodle 2.7 or later requires at least PHP 5.4.4 (currently using version $phpversion).\n");
151
152
    fwrite(STDERR, "Please upgrade your server software or install older Moodle version.\n");
    exit(1);
153
154
155
}

// set up configuration
156
global $CFG;
157
$CFG = new stdClass();
158
$CFG->lang                 = 'en';
159
$CFG->dirroot              = dirname(dirname(dirname(__FILE__)));
160
161
162
163
$CFG->libdir               = "$CFG->dirroot/lib";
$CFG->wwwroot              = "http://localhost";
$CFG->httpswwwroot         = $CFG->wwwroot;
$CFG->docroot              = 'http://docs.moodle.org';
skodak's avatar
skodak committed
164
$CFG->running_installer    = true;
165
$CFG->early_install_lang   = true;
166
$CFG->ostype               = (stristr(PHP_OS, 'win') && !stristr(PHP_OS, 'darwin')) ? 'WINDOWS' : 'UNIX';
167
$CFG->dboptions            = array();
168
169
170
$CFG->debug                = (E_ALL | E_STRICT);
$CFG->debugdisplay         = true;
$CFG->debugdeveloper       = true;
171

172
173
174
175
176
177
178
$parts = explode('/', str_replace('\\', '/', dirname(dirname(__FILE__))));
$CFG->admin                = array_pop($parts);

//point pear include path to moodles lib/pear so that includes and requires will search there for files before anywhere else
//the problem is that we need specific version of quickforms and hacked excel files :-(
ini_set('include_path', $CFG->libdir.'/pear' . PATH_SEPARATOR . ini_get('include_path'));

179
require_once($CFG->libdir.'/classes/component.php');
180
require_once($CFG->libdir.'/classes/text.php');
181
182
183
require_once($CFG->libdir.'/classes/string_manager.php');
require_once($CFG->libdir.'/classes/string_manager_install.php');
require_once($CFG->libdir.'/classes/string_manager_standard.php');
184
185
186
187
188
189
190
191
192
require_once($CFG->libdir.'/installlib.php');
require_once($CFG->libdir.'/clilib.php');
require_once($CFG->libdir.'/setuplib.php');
require_once($CFG->libdir.'/weblib.php');
require_once($CFG->libdir.'/dmllib.php');
require_once($CFG->libdir.'/moodlelib.php');
require_once($CFG->libdir.'/deprecatedlib.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/componentlib.class.php');
193
require_once($CFG->dirroot.'/cache/lib.php');
194

195
196
197
198
199
200
201
202
// Register our classloader, in theory somebody might want to replace it to load other hacked core classes.
// Required because the database checks below lead to session interaction which is going to lead us to requiring autoloaded classes.
if (defined('COMPONENT_CLASSLOADER')) {
    spl_autoload_register(COMPONENT_CLASSLOADER);
} else {
    spl_autoload_register('core_component::classloader');
}

203
204
205
require($CFG->dirroot.'/version.php');
$CFG->target_release = $release;

206
\core\session\manager::init_empty_session();
207
208
209
210
211
212
213
214
215
216
217
global $SESSION;
global $USER;

global $COURSE;
$COURSE = new stdClass();
$COURSE->id = 1;

global $SITE;
$SITE = $COURSE;
define('SITEID', 1);

218
219
//Database types
$databases = array('mysqli' => moodle_database::get_driver_instance('mysqli', 'native'),
220
                   'mariadb'=> moodle_database::get_driver_instance('mariadb', 'native'),
221
222
                   'pgsql'  => moodle_database::get_driver_instance('pgsql',  'native'),
                   'oci'    => moodle_database::get_driver_instance('oci',    'native'),
223
224
                   'sqlsrv' => moodle_database::get_driver_instance('sqlsrv', 'native'), // MS SQL*Server PHP driver
                   'mssql'  => moodle_database::get_driver_instance('mssql',  'native'), // FreeTDS driver
225
226
227
228
229
230
231
                  );
foreach ($databases as $type=>$database) {
    if ($database->driver_installed() !== true) {
        unset($databases[$type]);
    }
}
if (empty($databases)) {
232
233
234
235
    $defaultdb = '';
} else {
    reset($databases);
    $defaultdb = key($databases);
236
237
238
}

// now get cli options
239
240
list($options, $unrecognized) = cli_get_params(
    array(
241
        'chmod'             => isset($distro->directorypermissions) ? sprintf('%04o',$distro->directorypermissions) : '2777', // let distros set dir permissions
242
243
        'lang'              => $CFG->lang,
        'wwwroot'           => '',
244
245
246
        'dataroot'          => empty($distro->dataroot) ? str_replace('\\', '/', dirname(dirname(dirname(dirname(__FILE__)))).'/moodledata'): $distro->dataroot, // initialised later after including libs or by distro
        'dbtype'            => empty($distro->dbtype) ? $defaultdb : $distro->dbtype, // let distro skip dbtype selection
        'dbhost'            => empty($distro->dbhost) ? 'localhost' : $distro->dbhost, // let distros set dbhost
247
        'dbname'            => 'moodle',
248
        'dbuser'            => empty($distro->dbuser) ? 'root' : $distro->dbuser, // let distros set dbuser
249
        'dbpass'            => '',
250
251
        'dbport'            => '',
        'dbsocket'          => '',
252
        'prefix'            => 'mdl_',
253
254
        'fullname'          => '',
        'shortname'         => '',
255
256
        'adminuser'         => 'admin',
        'adminpass'         => '',
257
        'adminemail'        => '',
258
259
        'non-interactive'   => false,
        'agree-license'     => false,
260
        'allow-unstable'    => false,
261
262
263
264
265
266
        'help'              => false
    ),
    array(
        'h' => 'help'
    )
);
267
268
269
270
271
272
273
274
275
276

$interactive = empty($options['non-interactive']);

// set up language
$lang = clean_param($options['lang'], PARAM_SAFEDIR);
if (file_exists($CFG->dirroot.'/install/lang/'.$lang)) {
    $CFG->lang = $lang;
}

if ($unrecognized) {
277
    $unrecognized = implode("\n  ", $unrecognized);
skodak's avatar
skodak committed
278
    cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
279
280
281
282
283
284
285
286
}

if ($options['help']) {
    echo $help;
    die;
}

//Print header
287
echo get_string('cliinstallheader', 'install', $CFG->target_release)."\n";
288
289
290

//Fist select language
if ($interactive) {
291
    cli_separator();
292
    $languages = get_string_manager()->get_list_of_translations();
293
294
    // Do not put the langs into columns because it is not compatible with RTL.
    $langlist = implode("\n", $languages);
295
    $default = $CFG->lang;
296
297
    cli_heading(get_string('availablelangs', 'install'));
    echo $langlist."\n";
298
    $prompt = get_string('clitypevaluedefault', 'admin', $CFG->lang);
299
300
301
302
303
304
    $error = '';
    do {
        echo $error;
        $input = cli_input($prompt, $default);
        $input = clean_param($input, PARAM_SAFEDIR);

305
        if (!file_exists($CFG->dirroot.'/install/lang/'.$input)) {
306
            $error = get_string('cliincorrectvalueretry', 'admin')."\n";
307
308
309
310
        } else {
            $error = '';
        }
    } while ($error !== '');
311
    $CFG->lang = $input;
312
} else {
313
    // already selected and verified
314
315
}

316
317
318
319
// Set directorypermissions first
$chmod = octdec(clean_param($options['chmod'], PARAM_INT));
if ($interactive) {
    cli_separator();
320
    cli_heading(get_string('datarootpermission', 'install'));
321
322
323
324
    $prompt = get_string('clitypevaluedefault', 'admin', decoct($chmod));
    $error = '';
    do {
        echo $error;
325
        $input = cli_input($prompt, decoct($chmod));
326
327
328
329
330
331
        $input = octdec(clean_param($input, PARAM_INT));
        if (empty($input)) {
            $error = get_string('cliincorrectvalueretry', 'admin')."\n";
        } else {
            $error = '';
        }
332
    } while ($error !== '');
333
334
335
336
337
338
339
340
341
    $chmod = $input;

} else {
    if (empty($chmod)) {
        $a = (object)array('option' => 'chmod', 'value' => decoct($chmod));
        cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
    }
}
$CFG->directorypermissions = $chmod;
Petr Škoda's avatar
Petr Škoda committed
342
343
$CFG->filepermissions      = ($CFG->directorypermissions & 0666);
$CFG->umaskpermissions     = (($CFG->directorypermissions & 0777) ^ 0777);
344
345
346
347
348

//We need wwwroot before we test dataroot
$wwwroot = clean_param($options['wwwroot'], PARAM_URL);
$wwwroot = trim($wwwroot, '/');
if ($interactive) {
349
350
    cli_separator();
    cli_heading(get_string('wwwroot', 'install'));
351
    if (strpos($wwwroot, 'http') === 0) {
352
        $prompt = get_string('clitypevaluedefault', 'admin', $wwwroot);
353
    } else {
354
355
        $wwwroot = null;
        $prompt = get_string('clitypevalue', 'admin');
356
357
358
359
360
361
362
363
    }
    $error = '';
    do {
        echo $error;
        $input = cli_input($prompt, $wwwroot);
        $input = clean_param($input, PARAM_URL);
        $input = trim($input, '/');
        if (strpos($input, 'http') !== 0) {
364
            $error = get_string('cliincorrectvalueretry', 'admin')."\n";
365
366
367
368
369
370
371
372
        } else {
            $error = '';
        }
    } while ($error !== '');
    $wwwroot = $input;

} else {
    if (strpos($wwwroot, 'http') !== 0) {
373
374
        $a = (object)array('option'=>'wwwroot', 'value'=>$wwwroot);
        cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
375
376
377
378
379
380
381
    }
}
$CFG->wwwroot       = $wwwroot;
$CFG->httpswwwroot  = $CFG->wwwroot;


//We need dataroot before lang download
382
$CFG->dataroot = $options['dataroot'];
383
if ($interactive) {
384
    cli_separator();
385
386
387
388
389
390
391
392
393
394
    $i=0;
    while(is_dataroot_insecure()) {
        $parrent = dirname($CFG->dataroot);
        $i++;
        if ($parrent == '/' or $parrent == '.' or preg_match('/^[a-z]:\\\?$/i', $parrent) or ($i > 100)) {
            $CFG->dataroot = ''; //can not find secure location for dataroot
            break;
        }
        $CFG->dataroot = dirname($parrent).'/moodledata';
    }
395
    cli_heading(get_string('dataroot', 'install'));
396
397
398
    $error = '';
    do {
        if ($CFG->dataroot !== '') {
399
            $prompt = get_string('clitypevaluedefault', 'admin', $CFG->dataroot);
400
        } else {
401
            $prompt = get_string('clitypevalue', 'admin');
402
403
404
405
        }
        echo $error;
        $CFG->dataroot = cli_input($prompt, $CFG->dataroot);
        if ($CFG->dataroot === '') {
406
            $error = get_string('cliincorrectvalueretry', 'admin')."\n";
407
408
        } else if (is_dataroot_insecure()) {
            $CFG->dataroot = '';
409
            $error = get_string('pathsunsecuredataroot', 'install')."\n";
410
        } else {
411
            if (install_init_dataroot($CFG->dataroot, $CFG->directorypermissions)) {
412
413
                $error = '';
            } else {
414
415
                $a = (object)array('dataroot' => $CFG->dataroot);
                $error = get_string('pathserrcreatedataroot', 'install', $a)."\n";
416
417
418
419
420
421
422
            }
        }

    } while ($error !== '');

} else {
    if (is_dataroot_insecure()) {
423
        cli_error(get_string('pathsunsecuredataroot', 'install'));
424
    }
425
    if (!install_init_dataroot($CFG->dataroot, $CFG->directorypermissions)) {
426
427
        $a = (object)array('dataroot' => $CFG->dataroot);
        cli_error(get_string('pathserrcreatedataroot', 'install', $a));
428
429
    }
}
430
431
432
$CFG->tempdir       = $CFG->dataroot.'/temp';
$CFG->cachedir      = $CFG->dataroot.'/cache';
$CFG->localcachedir = $CFG->dataroot.'/localcache';
433

434
435
436
437
438
439
440
441
442
443
// download required lang packs
if ($CFG->lang !== 'en') {
    $installer = new lang_installer($CFG->lang);
    $results = $installer->run();
    foreach ($results as $langcode => $langstatus) {
        if ($langstatus === lang_installer::RESULT_DOWNLOADERROR) {
            $a       = new stdClass();
            $a->url  = $installer->lang_pack_url($langcode);
            $a->dest = $CFG->dataroot.'/lang';
            cli_problem(get_string('remotedownloaderror', 'error', $a));
444
445
446
447
        }
    }
}

448
// switch the string_manager instance to stop using install/lang/
449
$CFG->early_install_lang = false;
450
451
$CFG->langotherroot      = $CFG->dataroot.'/lang';
$CFG->langlocalroot      = $CFG->dataroot.'/lang';
452
get_string_manager(true);
453

454
455
456
457
458
459
460
461
462
// make sure we are installing stable release or require a confirmation
if (isset($maturity)) {
    if (($maturity < MATURITY_STABLE) and !$options['allow-unstable']) {
        $maturitylevel = get_string('maturity'.$maturity, 'admin');

        if ($interactive) {
            cli_separator();
            cli_heading(get_string('notice'));
            echo get_string('maturitycorewarning', 'admin', $maturitylevel) . PHP_EOL;
463
            echo get_string('morehelp') . ': ' . get_docs_url('admin/versions') . PHP_EOL;
Petr Skoda's avatar
Petr Skoda committed
464
            echo get_string('continue') . PHP_EOL;
465
466
467
468
469
470
            $prompt = get_string('cliyesnoprompt', 'admin');
            $input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin')));
            if ($input == get_string('clianswerno', 'admin')) {
                exit(1);
            }
        } else {
471
472
            cli_problem(get_string('maturitycorewarning', 'admin', $maturitylevel));
            cli_error(get_string('maturityallowunstable', 'admin'));
473
474
475
476
        }
    }
}

477
478
479
// ask for db type - show only drivers available
if ($interactive) {
    $options['dbtype'] = strtolower($options['dbtype']);
480
481
    cli_separator();
    cli_heading(get_string('databasetypehead', 'install'));
482
    foreach ($databases as $type=>$database) {
483
        echo " $type \n";
484
485
    }
    if (!empty($databases[$options['dbtype']])) {
486
        $prompt = get_string('clitypevaluedefault', 'admin', $options['dbtype']);
487
    } else {
488
        $prompt = get_string('clitypevalue', 'admin');
489
490
491
492
493
    }
    $CFG->dbtype = cli_input($prompt, $options['dbtype'], array_keys($databases));

} else {
    if (empty($databases[$options['dbtype']])) {
494
495
        $a = (object)array('option'=>'dbtype', 'value'=>$options['dbtype']);
        cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
496
497
498
499
500
501
502
503
    }
    $CFG->dbtype = $options['dbtype'];
}
$database = $databases[$CFG->dbtype];


// ask for db host
if ($interactive) {
504
505
    cli_separator();
    cli_heading(get_string('databasehost', 'install'));
506
    if ($options['dbhost'] !== '') {
507
        $prompt = get_string('clitypevaluedefault', 'admin', $options['dbhost']);
508
    } else {
509
        $prompt = get_string('clitypevalue', 'admin');
510
511
512
513
514
515
516
517
518
    }
    $CFG->dbhost = cli_input($prompt, $options['dbhost']);

} else {
    $CFG->dbhost = $options['dbhost'];
}

// ask for db name
if ($interactive) {
519
520
    cli_separator();
    cli_heading(get_string('databasename', 'install'));
521
    if ($options['dbname'] !== '') {
522
        $prompt = get_string('clitypevaluedefault', 'admin', $options['dbname']);
523
    } else {
524
        $prompt = get_string('clitypevalue', 'admin');
525
526
527
528
529
530
531
532
533
    }
    $CFG->dbname = cli_input($prompt, $options['dbname']);

} else {
    $CFG->dbname = $options['dbname'];
}

// ask for db prefix
if ($interactive) {
534
535
    cli_separator();
    cli_heading(get_string('dbprefix', 'install'));
536
537
    //TODO: solve somehow the prefix trouble for oci
    if ($options['prefix'] !== '') {
538
        $prompt = get_string('clitypevaluedefault', 'admin', $options['prefix']);
539
    } else {
540
        $prompt = get_string('clitypevalue', 'admin');
541
542
543
544
545
546
547
    }
    $CFG->prefix = cli_input($prompt, $options['prefix']);

} else {
    $CFG->prefix = $options['prefix'];
}

548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
// ask for db port
if ($interactive) {
    cli_separator();
    cli_heading(get_string('databaseport', 'install'));
    $prompt = get_string('clitypevaluedefault', 'admin', $options['dbport']);
    $CFG->dboptions['dbport'] = (int)cli_input($prompt, $options['dbport']);

} else {
    $CFG->dboptions['dbport'] = (int)$options['dbport'];
}
if ($CFG->dboptions['dbport'] <= 0) {
    $CFG->dboptions['dbport'] = '';
}

// ask for db socket
if ($CFG->ostype === 'WINDOWS') {
    $CFG->dboptions['dbsocket'] = '';

} else if ($interactive and empty($CFG->dboptions['dbport'])) {
    cli_separator();
    cli_heading(get_string('databasesocket', 'install'));
    $prompt = get_string('clitypevaluedefault', 'admin', $options['dbsocket']);
    $CFG->dboptions['dbsocket'] = cli_input($prompt, $options['dbsocket']);

} else {
    $CFG->dboptions['dbsocket'] = $options['dbsocket'];
}

576
577
// ask for db user
if ($interactive) {
578
579
    cli_separator();
    cli_heading(get_string('databaseuser', 'install'));
580
    if ($options['dbuser'] !== '') {
581
        $prompt = get_string('clitypevaluedefault', 'admin', $options['dbuser']);
582
    } else {
583
        $prompt = get_string('clitypevalue', 'admin');
584
585
586
587
588
589
590
591
592
    }
    $CFG->dbuser = cli_input($prompt, $options['dbuser']);

} else {
    $CFG->dbuser = $options['dbuser'];
}

// ask for db password
if ($interactive) {
593
594
    cli_separator();
    cli_heading(get_string('databasepass', 'install'));
595
596
    do {
        if ($options['dbpass'] !== '') {
597
            $prompt = get_string('clitypevaluedefault', 'admin', $options['dbpass']);
598
        } else {
599
            $prompt = get_string('clitypevalue', 'admin');
600
601
602
        }

        $CFG->dbpass = cli_input($prompt, $options['dbpass']);
603
        if (function_exists('distro_pre_create_db')) { // Hook for distros needing to do something before DB creation
604
            $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);
605
        }
606
        $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']));
607
608
609
610
    } while ($hint_database !== '');

} else {
    $CFG->dbpass = $options['dbpass'];
611
    $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']));
612
    if ($hint_database !== '') {
613
        cli_error(get_string('dbconnectionerror', 'install'));
614
615
616
    }
}

617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
// ask for fullname
if ($interactive) {
    cli_separator();
    cli_heading(get_string('fullsitename', 'moodle'));

    if ($options['fullname'] !== '') {
        $prompt = get_string('clitypevaluedefault', 'admin', $options['fullname']);
    } else {
        $prompt = get_string('clitypevalue', 'admin');
    }

    do {
        $options['fullname'] = cli_input($prompt, $options['fullname']);
    } while (empty($options['fullname']));
} else {
    if (empty($options['fullname'])) {
        $a = (object)array('option'=>'fullname', 'value'=>$options['fullname']);
        cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
    }
}

// ask for shortname
if ($interactive) {
    cli_separator();
    cli_heading(get_string('shortsitename', 'moodle'));

    if ($options['shortname'] !== '') {
        $prompt = get_string('clitypevaluedefault', 'admin', $options['shortname']);
    } else {
        $prompt = get_string('clitypevalue', 'admin');
    }

    do {
        $options['shortname'] = cli_input($prompt, $options['shortname']);
    } while (empty($options['shortname']));
} else {
    if (empty($options['shortname'])) {
        $a = (object)array('option'=>'shortname', 'value'=>$options['shortname']);
        cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
    }
}

659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
// ask for admin user name
if ($interactive) {
    cli_separator();
    cli_heading(get_string('cliadminusername', 'install'));
    if (!empty($options['adminuser'])) {
        $prompt = get_string('clitypevaluedefault', 'admin', $options['adminuser']);
    } else {
        $prompt = get_string('clitypevalue', 'admin');
    }
    do {
        $options['adminuser'] = cli_input($prompt, $options['adminuser']);
    } while (empty($options['adminuser']) or $options['adminuser'] === 'guest');
} else {
    if (empty($options['adminuser']) or $options['adminuser'] === 'guest') {
        $a = (object)array('option'=>'adminuser', 'value'=>$options['adminuser']);
        cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
    }
}

678
679
// ask for admin user password
if ($interactive) {
680
681
682
    cli_separator();
    cli_heading(get_string('cliadminpassword', 'install'));
    $prompt = get_string('clitypevalue', 'admin');
683
    do {
684
685
        $options['adminpass'] = cli_input($prompt);
    } while (empty($options['adminpass']) or $options['adminpass'] === 'admin');
686
} else {
687
688
    if (empty($options['adminpass']) or $options['adminpass'] === 'admin') {
        $a = (object)array('option'=>'adminpass', 'value'=>$options['adminpass']);
689
        cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
690
691
692
    }
}

693
694
695
696
697
698
699
700
701
702
703
704
705
706
// Ask for the admin email address.
if ($interactive) {
    cli_separator();
    cli_heading(get_string('cliadminemail', 'install'));
    $prompt = get_string('clitypevaluedefault', 'admin', $options['adminemail']);
    $options['adminemail'] = cli_input($prompt);
}

// Validate that the address provided was an e-mail address.
if (!empty($options['adminemail']) && !validate_email($options['adminemail'])) {
    $a = (object) array('option' => 'adminemail', 'value' => $options['adminemail']);
    cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
}

707
if ($interactive) {
708
    if (!$options['agree-license']) {
skodak's avatar
skodak committed
709
710
        cli_separator();
        cli_heading(get_string('copyrightnotice'));
711
        echo "Moodle  - Modular Object-Oriented Dynamic Learning Environment\n";
712
        echo get_string('gpl3')."\n\n";
skodak's avatar
skodak committed
713
        echo get_string('doyouagree')."\n";
714
        $prompt = get_string('cliyesnoprompt', 'admin');
715
        $input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin')));
716
717
718
        if ($input == get_string('clianswerno', 'admin')) {
            exit(1);
        }
719
720
    }
} else {
721
    if (!$options['agree-license']) {
722
        cli_error(get_string('climustagreelicense', 'install'));
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
    }
}

// Finally we have all info needed for config.php
$configphp = install_generate_configphp($database, $CFG);
umask(0137);
if (($fh = fopen($configfile, 'w')) !== false) {
    fwrite($fh, $configphp);
    fclose($fh);
}

if (!file_exists($configfile)) {
    cli_error('Can not create config file.');
}

738
739
740
741
742
743
744
745
746
747
748
749
750
// remember selected language
$installlang = $CFG->lang;
// return back to original dir before executing setup.php which changes the dir again
chdir($olddir);
// We have config.php, it is a real php script from now on :-)
require($configfile);

// use selected language
$CFG->lang = $installlang;
$SESSION->lang = $CFG->lang;

require("$CFG->dirroot/version.php");

751
// Test environment first.
752
require_once($CFG->libdir . '/environmentlib.php');
753
754
755
756
757
758
759
760
761
762
763
list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
if (!$envstatus) {
    $errors = environment_get_errors($environment_results);
    cli_heading(get_string('environment', 'admin'));
    foreach ($errors as $error) {
        list($info, $report) = $error;
        echo "!! $info !!\n$report\n\n";
    }
    exit(1);
}

764
// Test plugin dependencies.
765
$failed = array();
766
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
767
    cli_problem(get_string('pluginscheckfailed', 'admin', array('pluginslist' => implode(', ', array_unique($failed)))));
768
769
770
    cli_error(get_string('pluginschecktodo', 'admin'));
}

771
install_cli_database($options, $interactive);
772

773
774
echo get_string('cliinstallfinished', 'install')."\n";
exit(0); // 0 means success