Passed
Push — master ( 0a87d5...5ba6bb )
by Julito
18:12
created

finishInstallationWithContainer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 73
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 40
nc 1
nop 16
dl 0
loc 73
rs 9.28
c 1
b 0
f 0

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\AccessUrl;
6
use Chamilo\CoreBundle\Entity\BranchSync;
7
use Chamilo\CoreBundle\Entity\Group;
8
use Chamilo\CoreBundle\Entity\TicketCategory;
9
use Chamilo\CoreBundle\Entity\TicketPriority;
10
use Chamilo\CoreBundle\Entity\TicketProject;
11
use Chamilo\CoreBundle\Entity\User;
12
use Chamilo\CoreBundle\Framework\Container;
13
use Chamilo\CoreBundle\Repository\GroupRepository;
14
use Chamilo\CoreBundle\Repository\Node\AccessUrlRepository;
15
use Chamilo\CoreBundle\Repository\Node\UserRepository;
16
use Chamilo\CoreBundle\ToolChain;
17
use Doctrine\Migrations\Configuration\Connection\ExistingConnection;
18
use Doctrine\Migrations\Configuration\Migration\PhpFile;
19
use Doctrine\Migrations\DependencyFactory;
20
use Doctrine\Migrations\Query\Query;
21
use Doctrine\ORM\EntityManager;
22
use Symfony\Component\DependencyInjection\Container as SymfonyContainer;
23
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
24
25
/*
26
 * Chamilo LMS
27
 * This file contains functions used by the install and upgrade scripts.
28
 *
29
 * Ideas for future additions:
30
 * - a function get_old_version_settings to retrieve the config file settings
31
 *   of older versions before upgrading.
32
 */
33
define('SYSTEM_CONFIG_FILENAME', 'configuration.dist.php');
34
define('USERNAME_MAX_LENGTH', 100);
35
36
/**
37
 * This function detects whether the system has been already installed.
38
 * It should be used for prevention from second running the installation
39
 * script and as a result - destroying a production system.
40
 *
41
 * @return bool The detected result;
42
 *
43
 * @author Ivan Tcholakov, 2010;
44
 */
45
function isAlreadyInstalledSystem()
46
{
47
    global $new_version, $_configuration;
48
49
    if (empty($new_version)) {
50
        return true; // Must be initialized.
51
    }
52
53
    $current_config_file = api_get_path(CONFIGURATION_PATH).'configuration.php';
54
    if (!file_exists($current_config_file)) {
55
        return false; // Configuration file does not exist, install the system.
56
    }
57
    require $current_config_file;
58
59
    $current_version = null;
60
    if (isset($_configuration['system_version'])) {
61
        $current_version = trim($_configuration['system_version']);
62
    }
63
64
    // If the current version is old, upgrading is assumed, the installer goes ahead.
65
    return empty($current_version) ? false : version_compare($current_version, $new_version, '>=');
66
}
67
68
/**
69
 * This function checks if a php extension exists or not and returns an HTML status string.
70
 *
71
 * @param string $extensionName Name of the PHP extension to be checked
72
 * @param string $returnSuccess Text to show when extension is available (defaults to 'Yes')
73
 * @param string $returnFailure Text to show when extension is available (defaults to 'No')
74
 * @param bool   $optional      Whether this extension is optional (then show unavailable text in orange rather than
75
 *                              red)
76
 * @param string $enabledTerm   If this string is not null, then use to check if the corresponding parameter is = 1.
77
 *                              If not, mention it's present but not enabled. For example, for opcache, this should be
78
 *                              'opcache.enable'
79
 *
80
 * @return string HTML string reporting the status of this extension. Language-aware.
81
 *
82
 * @author  Christophe Gesch??
83
 * @author  Patrick Cool <[email protected]>, Ghent University
84
 * @author  Yannick Warnier <[email protected]>
85
 */
86
function checkExtension(
87
    $extensionName,
88
    $returnSuccess = 'Yes',
89
    $returnFailure = 'No',
90
    $optional = false,
91
    $enabledTerm = ''
92
) {
93
    if (extension_loaded($extensionName)) {
94
        if (!empty($enabledTerm)) {
95
            $isEnabled = ini_get($enabledTerm);
96
            if ('1' == $isEnabled) {
97
                return Display::label($returnSuccess, 'success');
98
            } else {
99
                if ($optional) {
100
                    return Display::label(get_lang('Extension installed but not enabled'), 'warning');
101
                }
102
103
                return Display::label(get_lang('Extension installed but not enabled'), 'important');
104
            }
105
        }
106
107
        return Display::label($returnSuccess, 'success');
108
    } else {
109
        if ($optional) {
110
            return Display::label($returnFailure, 'warning');
111
        }
112
113
        return Display::label($returnFailure, 'important');
114
    }
115
}
116
117
/**
118
 * This function checks whether a php setting matches the recommended value.
119
 *
120
 * @param string $phpSetting       A PHP setting to check
121
 * @param string $recommendedValue A recommended value to show on screen
122
 * @param mixed  $returnSuccess    What to show on success
123
 * @param mixed  $returnFailure    What to show on failure
124
 *
125
 * @return string A label to show
126
 *
127
 * @author Patrick Cool <[email protected]>, Ghent University
128
 */
129
function checkPhpSetting(
130
    $phpSetting,
131
    $recommendedValue,
132
    $returnSuccess = false,
133
    $returnFailure = false
134
) {
135
    $currentPhpValue = getPhpSetting($phpSetting);
136
    if ($currentPhpValue == $recommendedValue) {
137
        return Display::label($currentPhpValue.' '.$returnSuccess, 'success');
138
    }
139
140
    return Display::label($currentPhpValue.' '.$returnSuccess, 'important');
141
}
142
143
/**
144
 * This function return the value of a php.ini setting if not "" or if exists,
145
 * otherwise return false.
146
 *
147
 * @param string $phpSetting The name of a PHP setting
148
 *
149
 * @return mixed The value of the setting, or false if not found
150
 */
151
function checkPhpSettingExists($phpSetting)
152
{
153
    if ('' != ini_get($phpSetting)) {
154
        return ini_get($phpSetting);
155
    }
156
157
    return false;
158
}
159
160
/**
161
 * Returns a textual value ('ON' or 'OFF') based on a requester 2-state ini- configuration setting.
162
 *
163
 * @param string $val a php ini value
164
 *
165
 * @return bool ON or OFF
166
 *
167
 * @author Joomla <http://www.joomla.org>
168
 */
169
function getPhpSetting($val)
170
{
171
    $value = ini_get($val);
172
    switch ($val) {
173
        case 'display_errors':
174
            global $originalDisplayErrors;
175
            $value = $originalDisplayErrors;
176
            break;
177
    }
178
179
    return '1' == $value ? 'ON' : 'OFF';
180
}
181
182
/**
183
 * This function returns a string "true" or "false" according to the passed parameter.
184
 *
185
 * @param int $var The variable to present as text
186
 *
187
 * @return string the string "true" or "false"
188
 *
189
 * @author Christophe Gesch??
190
 */
191
function trueFalse($var)
192
{
193
    return $var ? 'true' : 'false';
194
}
195
196
/**
197
 * Detects browser's language.
198
 *
199
 * @return string Returns a language identificator, i.e. 'english', 'spanish', ...
200
 *
201
 * @author Ivan Tcholakov, 2010
202
 */
203
function detect_browser_language()
204
{
205
    static $language_index = [
206
        'ar' => 'arabic',
207
        'ast' => 'asturian',
208
        'bg' => 'bulgarian',
209
        'bs' => 'bosnian',
210
        'ca' => 'catalan',
211
        'zh' => 'simpl_chinese',
212
        'zh-tw' => 'trad_chinese',
213
        'cs' => 'czech',
214
        'da' => 'danish',
215
        'prs' => 'dari',
216
        'de' => 'german',
217
        'el' => 'greek',
218
        'en' => 'english',
219
        'es' => 'spanish',
220
        'eo' => 'esperanto',
221
        'eu' => 'basque',
222
        'fa' => 'persian',
223
        'fr' => 'french',
224
        'fur' => 'friulian',
225
        'gl' => 'galician',
226
        'ka' => 'georgian',
227
        'hr' => 'croatian',
228
        'he' => 'hebrew',
229
        'hi' => 'hindi',
230
        'id' => 'indonesian',
231
        'it' => 'italian',
232
        'ko' => 'korean',
233
        'lv' => 'latvian',
234
        'lt' => 'lithuanian',
235
        'mk' => 'macedonian',
236
        'hu' => 'hungarian',
237
        'ms' => 'malay',
238
        'nl' => 'dutch',
239
        'ja' => 'japanese',
240
        'no' => 'norwegian',
241
        'oc' => 'occitan',
242
        'ps' => 'pashto',
243
        'pl' => 'polish',
244
        'pt' => 'portuguese',
245
        'pt-br' => 'brazilian',
246
        'ro' => 'romanian',
247
        'qu' => 'quechua_cusco',
248
        'ru' => 'russian',
249
        'sk' => 'slovak',
250
        'sl' => 'slovenian',
251
        'sr' => 'serbian',
252
        'fi' => 'finnish',
253
        'sv' => 'swedish',
254
        'th' => 'thai',
255
        'tr' => 'turkish',
256
        'uk' => 'ukrainian',
257
        'vi' => 'vietnamese',
258
        'sw' => 'swahili',
259
        'yo' => 'yoruba',
260
    ];
261
262
    $system_available_languages = get_language_folder_list();
263
    if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
264
        $accept_languages = strtolower(str_replace('_', '-', $_SERVER['HTTP_ACCEPT_LANGUAGE']));
265
        foreach ($language_index as $code => $language) {
266
            if (0 === strpos($accept_languages, $code)) {
267
                if (!empty($system_available_languages[$language])) {
268
                    return $language;
269
                }
270
            }
271
        }
272
    }
273
274
    if (isset($_SERVER['HTTP_USER_AGENT'])) {
275
        $user_agent = strtolower(str_replace('_', '-', $_SERVER['HTTP_USER_AGENT']));
276
        foreach ($language_index as $code => $language) {
277
            if (@preg_match("/[\[\( ]{$code}[;,_\-\)]/", $user_agent)) {
278
                if (!empty($system_available_languages[$language])) {
279
                    return $language;
280
                }
281
            }
282
        }
283
    }
284
285
    return 'english';
286
}
287
288
/**
289
 * This function checks if the given folder is writable.
290
 *
291
 * @param string $folder     Full path to a folder
292
 * @param bool   $suggestion Whether to show a suggestion or not
293
 *
294
 * @return string
295
 */
296
function check_writable($folder, $suggestion = false)
297
{
298
    if (is_writable($folder)) {
299
        return Display::label(get_lang('Writable'), 'success');
300
    } else {
301
        if ($suggestion) {
302
            return Display::label(get_lang('Not writable'), 'info');
303
        } else {
304
            return Display::label(get_lang('Not writable'), 'important');
305
        }
306
    }
307
}
308
309
/**
310
 * This function checks if the given folder is readable.
311
 *
312
 * @param string $folder     Full path to a folder
313
 * @param bool   $suggestion Whether to show a suggestion or not
314
 *
315
 * @return string
316
 */
317
function checkReadable($folder, $suggestion = false)
318
{
319
    if (is_readable($folder)) {
320
        return Display::label(get_lang('Readable'), 'success');
321
    } else {
322
        if ($suggestion) {
323
            return Display::label(get_lang('Not readable'), 'info');
324
        } else {
325
            return Display::label(get_lang('Not readable'), 'important');
326
        }
327
    }
328
}
329
330
/**
331
 * We assume this function is called from install scripts that reside inside the install folder.
332
 */
333
function set_file_folder_permissions()
334
{
335
    @chmod('.', 0755); //set permissions on install dir
336
    @chmod('..', 0755); //set permissions on parent dir of install dir
337
}
338
339
/**
340
 * Write the main system config file.
341
 *
342
 * @param string $path Path to the config file
343
 */
344
function writeSystemConfigFile($path)
345
{
346
    $content = file_get_contents(__DIR__.'/'.SYSTEM_CONFIG_FILENAME);
347
    $config['{DATE_GENERATED}'] = date('r');
348
    $config['{SECURITY_KEY}'] = md5(uniqid(rand().time()));
349
350
    foreach ($config as $key => $value) {
351
        $content = str_replace($key, $value, $content);
352
    }
353
    $fp = @fopen($path, 'w');
354
355
    if (!$fp) {
0 ignored issues
show
introduced by
$fp is of type false|resource, thus it always evaluated to false.
Loading history...
356
        echo '<strong>
357
                <font color="red">Your script doesn\'t have write access to the config directory</font></strong><br />
358
                <em>('.str_replace('\\', '/', realpath($path)).')</em><br /><br />
359
                You probably do not have write access on Chamilo root directory,
360
                i.e. you should <em>CHMOD 777</em> or <em>755</em> or <em>775</em>.<br /><br />
361
                Your problems can be related on two possible causes:<br />
362
                <ul>
363
                  <li>Permission problems.<br />Try initially with <em>chmod -R 777</em> and increase restrictions gradually.</li>
364
                  <li>PHP is running in <a href="http://www.php.net/manual/en/features.safe-mode.php" target="_blank">Safe-Mode</a>.
365
                  If possible, try to switch it off.</li>
366
                </ul>
367
                <a href="http://forum.chamilo.org/" target="_blank">Read about this problem in Support Forum</a><br /><br />
368
                Please go back to step 5.
369
                <p><input type="submit" name="step5" value="&lt; Back" /></p>
370
                </td></tr></table></form></body></html>';
371
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
372
    }
373
374
    fwrite($fp, $content);
375
    fclose($fp);
376
}
377
378
/**
379
 * Returns a list of language directories.
380
 */
381
function get_language_folder_list()
382
{
383
    return [
384
        'ar' => 'arabic',
385
        'ast' => 'asturian',
386
        'bg' => 'bulgarian',
387
        'bs' => 'bosnian',
388
        'ca' => 'catalan',
389
        'zh' => 'simpl_chinese',
390
        'zh-tw' => 'trad_chinese',
391
        'cs' => 'czech',
392
        'da' => 'danish',
393
        'prs' => 'dari',
394
        'de' => 'german',
395
        'el' => 'greek',
396
        'en' => 'english',
397
        'es' => 'spanish',
398
        'eo' => 'esperanto',
399
        'eu' => 'basque',
400
        'fa' => 'persian',
401
        'fr' => 'french',
402
        'fur' => 'friulian',
403
        'gl' => 'galician',
404
        'ka' => 'georgian',
405
        'hr' => 'croatian',
406
        'he' => 'hebrew',
407
        'hi' => 'hindi',
408
        'id' => 'indonesian',
409
        'it' => 'italian',
410
        'ko' => 'korean',
411
        'lv' => 'latvian',
412
        'lt' => 'lithuanian',
413
        'mk' => 'macedonian',
414
        'hu' => 'hungarian',
415
        'ms' => 'malay',
416
        'nl' => 'dutch',
417
        'ja' => 'japanese',
418
        'no' => 'norwegian',
419
        'oc' => 'occitan',
420
        'ps' => 'pashto',
421
        'pl' => 'polish',
422
        'pt' => 'portuguese',
423
        'pt-br' => 'brazilian',
424
        'ro' => 'romanian',
425
        'qu' => 'quechua_cusco',
426
        'ru' => 'russian',
427
        'sk' => 'slovak',
428
        'sl' => 'slovenian',
429
        'sr' => 'serbian',
430
        'fi' => 'finnish',
431
        'sv' => 'swedish',
432
        'th' => 'thai',
433
        'tr' => 'turkish',
434
        'uk' => 'ukrainian',
435
        'vi' => 'vietnamese',
436
        'sw' => 'swahili',
437
        'yo' => 'yoruba',
438
    ];
439
}
440
441
/**
442
 * This function returns the value of a parameter from the configuration file.
443
 *
444
 * WARNING - this function relies heavily on global variables $updateFromConfigFile
445
 * and $configFile, and also changes these globals. This can be rewritten.
446
 *
447
 * @param string $param      the parameter of which the value is returned
448
 * @param string $updatePath If we want to give the path rather than take it from POST
449
 *
450
 * @return string the value of the parameter
451
 *
452
 * @author Olivier Brouckaert
453
 * @author Reworked by Ivan Tcholakov, 2010
454
 */
455
function get_config_param($param, $updatePath = '')
456
{
457
    global $updateFromConfigFile;
458
    if (empty($updatePath) && !empty($_POST['updatePath'])) {
459
        $updatePath = $_POST['updatePath'];
460
    }
461
462
    if (empty($updatePath)) {
463
        $updatePath = api_get_path(SYMFONY_SYS_PATH);
464
    }
465
    $updatePath = api_add_trailing_slash(str_replace('\\', '/', realpath($updatePath)));
466
467
    if (empty($updateFromConfigFile)) {
468
        // If update from previous install was requested,
469
        if (file_exists($updatePath.'app/config/configuration.php')) {
470
            $updateFromConfigFile = 'app/config/configuration.php';
471
        } else {
472
            // Give up recovering.
473
            return null;
474
        }
475
    }
476
477
    if (file_exists($updatePath.$updateFromConfigFile) &&
478
        !is_dir($updatePath.$updateFromConfigFile)
479
    ) {
480
        require $updatePath.$updateFromConfigFile;
481
        $config = new Laminas\Config\Config($_configuration);
482
483
        return $config->get($param);
484
    }
485
486
    error_log('Config array could not be found in get_config_param()', 0);
487
488
    return null;
489
}
490
491
/**
492
 * Gets a configuration parameter from the database. Returns returns null on failure.
493
 *
494
 * @param string $param Name of param we want
495
 *
496
 * @return mixed The parameter value or null if not found
497
 */
498
function get_config_param_from_db($param = '')
499
{
500
    $param = Database::escape_string($param);
501
502
    if (false !== ($res = Database::query("SELECT * FROM settings_current WHERE variable = '$param'"))) {
503
        if (Database::num_rows($res) > 0) {
504
            $row = Database::fetch_array($res);
505
506
            return $row['selected_value'];
507
        }
508
    }
509
510
    return null;
511
}
512
513
/**
514
 * Connect to the database and returns the entity manager.
515
 *
516
 * @param string $host
517
 * @param string $username
518
 * @param string $password
519
 * @param string $databaseName
520
 * @param int    $port
521
 *
522
 * @return \Database
523
 */
524
function connectToDatabase(
525
    $host,
526
    $username,
527
    $password,
528
    $databaseName,
529
    $port = 3306
530
) {
531
    $database = new \Database();
532
    $database->connect(
533
        [
534
            'driver' => 'pdo_mysql',
535
            'host' => $host,
536
            'port' => $port,
537
            'user' => $username,
538
            'password' => $password,
539
            'dbname' => $databaseName,
540
        ]
541
    );
542
543
    return $database;
544
}
545
546
/**
547
 * This function prints class=active_step $current_step=$param.
548
 *
549
 * @param int $param A step in the installer process
550
 *
551
 * @author Patrick Cool <[email protected]>, Ghent University
552
 */
553
function step_active($param)
554
{
555
    global $current_step;
556
    if ($param == $current_step) {
557
        echo 'active';
558
    }
559
}
560
561
/**
562
 * This function displays the Step X of Y -.
563
 *
564
 * @return string String that says 'Step X of Y' with the right values
565
 */
566
function display_step_sequence()
567
{
568
    global $current_step;
569
570
    return get_lang('Step'.$current_step).' &ndash; ';
571
}
572
573
/**
574
 * Displays a drop down box for selection the preferred language.
575
 */
576
function display_language_selection_box($name = 'language_list', $default_language = 'en')
577
{
578
    // Reading language list.
579
    $language_list = get_language_folder_list();
580
581
    // Sanity checks due to the possibility for customizations.
582
    if (!is_array($language_list) || empty($language_list)) {
583
        $language_list = ['en' => 'English'];
584
    }
585
586
    // Sorting again, if it is necessary.
587
    //asort($language_list);
588
589
    // More sanity checks.
590
    if (!array_key_exists($default_language, $language_list)) {
591
        if (array_key_exists('en', $language_list)) {
592
            $default_language = 'en';
593
        } else {
594
            $language_keys = array_keys($language_list);
595
            $default_language = $language_keys[0];
596
        }
597
    }
598
599
    // Displaying the box.
600
    return Display::select(
601
        'language_list',
602
        $language_list,
603
        $default_language,
604
        ['class' => 'form-control'],
605
        false
606
    );
607
}
608
609
/**
610
 * This function displays a language dropdown box so that the installatioin
611
 * can be done in the language of the user.
612
 */
613
function display_language_selection()
614
{
615
    ?>
616
        <div class="install-icon">
617
            <img width="150px;" src="chamilo-install.svg"/>
618
        </div>
619
        <h2 class="text-2xl">
620
            <?php echo display_step_sequence(); ?>
621
            <?php echo get_lang('Installation Language'); ?>
622
        </h2>
623
        <label for="language_list"><?php echo get_lang('Please select installation language'); ?></label>
624
        <div class="form-group">
625
            <?php echo display_language_selection_box('language_list', api_get_interface_language()); ?>
626
        </div>
627
        <button type="submit" name="step1" class="btn btn-success" value="<?php echo get_lang('Next'); ?>">
628
            <em class="fa fa-forward"> </em>
629
            <?php echo get_lang('Next'); ?>
630
        </button>
631
        <input type="hidden" name="is_executable" id="is_executable" value="-" />
632
        <div class="RequirementHeading">
633
            <?php echo get_lang('Cannot find your language in the list? Contact us at [email protected] to contribute as a translator.'); ?>
634
        </div>
635
<?php
636
}
637
638
/**
639
 * This function displays the requirements for installing Chamilo.
640
 *
641
 * @param string $installType
642
 * @param bool   $badUpdatePath
643
 * @param bool   $badUpdatePath
644
 * @param string $updatePath         The updatePath given (if given)
645
 * @param array  $upgradeFromVersion The different subversions from version 1.9
646
 *
647
 * @author unknow
648
 * @author Patrick Cool <[email protected]>, Ghent University
649
 */
650
function display_requirements(
651
    $installType,
652
    $badUpdatePath,
653
    $updatePath = '',
654
    $upgradeFromVersion = []
655
) {
656
    global $_setting, $originalMemoryLimit;
657
658
    $dir = api_get_path(SYS_ARCHIVE_PATH).'temp/';
659
    $fileToCreate = 'test';
660
661
    $perms_dir = [0777, 0755, 0775, 0770, 0750, 0700];
662
    $perms_fil = [0666, 0644, 0664, 0660, 0640, 0600];
663
    $course_test_was_created = false;
664
    $dir_perm_verified = 0777;
665
666
    foreach ($perms_dir as $perm) {
667
        $r = @mkdir($dir, $perm);
668
        if (true === $r) {
669
            $dir_perm_verified = $perm;
670
            $course_test_was_created = true;
671
            break;
672
        }
673
    }
674
675
    $fil_perm_verified = 0666;
676
    $file_course_test_was_created = false;
677
    if (is_dir($dir)) {
678
        foreach ($perms_fil as $perm) {
679
            if (true == $file_course_test_was_created) {
680
                break;
681
            }
682
            $r = @touch($dir.'/'.$fileToCreate, $perm);
683
            if (true === $r) {
684
                $fil_perm_verified = $perm;
685
                $file_course_test_was_created = true;
686
            }
687
        }
688
    }
689
690
    @unlink($dir.'/'.$fileToCreate);
691
    @rmdir($dir);
692
693
    echo '<h2 class="install-title">'.display_step_sequence().get_lang('Requirements').'</h2>';
694
    echo '<div class="RequirementText">';
695
    echo '<strong>'.get_lang('Please read the following requirements thoroughly.').'</strong><br />';
696
    echo get_lang('For more details').'
697
        <a href="../../documentation/installation_guide.html" target="_blank">'.
698
        get_lang('Read the installation guide').'</a>.<br />'."\n";
699
700
    if ('update' == $installType) {
701
        echo get_lang(
702
            'If you plan to upgrade from an older version of Chamilo, you might want to <a href="../../documentation/changelog.html" target="_blank">have a look at the changelog</a> to know what\'s new and what has been changed').'<br />';
703
    }
704
    echo '</div>';
705
706
    //  SERVER REQUIREMENTS
707
    echo '<h4 class="install-subtitle">'.get_lang('Server requirements').'</h4>';
708
    $timezone = checkPhpSettingExists('date.timezone');
709
    if (!$timezone) {
710
        echo "<div class='alert alert-warning'>
711
            <i class=\"fa fa-exclamation-triangle\" aria-hidden=\"true\"></i>&nbsp;".
712
            get_lang('We have detected that your PHP installation does not define the date.timezone setting. This is a requirement of Chamilo. Please make sure it is configured by checking your php.ini configuration, otherwise you will run into problems. We warned you!').'</div>';
713
    }
714
715
    echo '<div class="install-requirement">'.get_lang('Server requirementsInfo').'</div>';
716
    echo '<div class="table-responsive">';
717
    echo '<table class="table table-bordered table-sm">
718
            <tr>
719
                <td class="requirements-item">'.get_lang('PHP version').' >= '.REQUIRED_PHP_VERSION.'</td>
720
                <td class="requirements-value">';
721
    if (version_compare(phpversion(), REQUIRED_PHP_VERSION, '>=') > 1) {
722
        echo '<strong class="text-danger">'.get_lang('PHP versionError').'</strong>';
723
    } else {
724
        echo '<strong class="text-success">'.get_lang('PHP versionOK').' '.phpversion().'</strong>';
725
    }
726
    echo '</td>
727
            </tr>
728
            <tr>
729
                <td class="requirements-item">
730
                    <a href="http://php.net/manual/en/book.session.php" target="_blank">Session</a>
731
                    '.get_lang('Support').'</td>
732
                <td class="requirements-value">'.
733
        checkExtension('session', get_lang('Yes'), get_lang('Sessions extension not available')).'</td>
734
            </tr>
735
            <tr>
736
                <td class="requirements-item">
737
                    <a href="http://php.net/manual/en/book.mysql.php" target="_blank">pdo_mysql</a> '.get_lang('Support').'</td>
738
                <td class="requirements-value">'.
739
                    checkExtension('pdo_mysql', get_lang('Yes'), get_lang('MySQL extension not available')).'</td>
740
            </tr>
741
            <tr>
742
                <td class="requirements-item">
743
                    <a href="http://php.net/manual/en/book.zip.php" target="_blank">Zip</a> '.get_lang('Support').'</td>
744
                <td class="requirements-value">'.
745
                checkExtension('zip', get_lang('Yes'), get_lang('Extension not available')).'</td>
746
            </tr>
747
            <tr>
748
                <td class="requirements-item">
749
                    <a href="http://php.net/manual/en/book.zlib.php" target="_blank">Zlib</a> '.get_lang('Support').'</td>
750
                <td class="requirements-value">'.
751
                checkExtension('zlib', get_lang('Yes'), get_lang('Zlib extension not available')).'</td>
752
            </tr>
753
            <tr>
754
                <td class="requirements-item">
755
                    <a href="http://php.net/manual/en/book.pcre.php" target="_blank">Perl-compatible regular expressions</a> '.get_lang('Support').'</td>
756
                <td class="requirements-value">'.
757
                    checkExtension('pcre', get_lang('Yes'), get_lang('PCRE extension not available')).'</td>
758
            </tr>
759
            <tr>
760
                <td class="requirements-item">
761
                    <a href="http://php.net/manual/en/book.xml.php" target="_blank">XML</a> '.get_lang('Support').'</td>
762
                <td class="requirements-value">'.
763
                    checkExtension('xml', get_lang('Yes'), get_lang('No')).'</td>
764
            </tr>
765
            <tr>
766
                <td class="requirements-item">
767
                    <a href="http://php.net/manual/en/book.intl.php" target="_blank">Internationalization</a> '.get_lang('Support').'</td>
768
                <td class="requirements-value">'.checkExtension('intl', get_lang('Yes'), get_lang('No')).'</td>
769
            </tr>
770
               <tr>
771
                <td class="requirements-item">
772
                    <a href="http://php.net/manual/en/book.json.php" target="_blank">JSON</a> '.get_lang('Support').'</td>
773
                <td class="requirements-value">'.checkExtension('json', get_lang('Yes'), get_lang('No')).'</td>
774
            </tr>
775
             <tr>
776
                <td class="requirements-item">
777
                    <a href="http://php.net/manual/en/book.image.php" target="_blank">GD</a> '.get_lang('Support').'</td>
778
                <td class="requirements-value">'.
779
                    checkExtension('gd', get_lang('Yes'), get_lang('GD Extension not available')).'</td>
780
            </tr>
781
            <tr>
782
                <td class="requirements-item">
783
                    <a href="http://php.net/manual/en/book.curl.php" target="_blank">cURL</a>'.get_lang('Support').'</td>
784
                <td class="requirements-value">'.
785
                checkExtension('curl', get_lang('Yes'), get_lang('No')).'</td>
786
            </tr>
787
            <tr>
788
                <td class="requirements-item">
789
                    <a href="http://php.net/manual/en/book.mbstring.php" target="_blank">Multibyte string</a> '.get_lang('Support').'</td>
790
                <td class="requirements-value">'.
791
                    checkExtension('mbstring', get_lang('Yes'), get_lang('MBString extension not available'), true).'</td>
792
            </tr>
793
           <tr>
794
                <td class="requirements-item">
795
                    <a href="http://php.net/manual/en/book.exif.php" target="_blank">Exif</a> '.get_lang('Support').'</td>
796
                <td class="requirements-value">'.
797
                    checkExtension('exif', get_lang('Yes'), get_lang('Exif extension not available'), true).'</td>
798
            </tr>
799
            <tr>
800
                <td class="requirements-item">
801
                    <a href="http://php.net/opcache" target="_blank">Zend OpCache</a> '.get_lang('Support').' ('.get_lang('Optional').')</td>
802
                <td class="requirements-value">'.
803
                    checkExtension('Zend OPcache', get_lang('Yes'), get_lang('No'), true, 'opcache.enable').'</td>
804
            </tr>
805
            <tr>
806
                <td class="requirements-item">
807
                    <a href="http://php.net/apcu" target="_blank">APCu</a> '.get_lang('Support').' ('.get_lang('Optional').')</td>
808
                <td class="requirements-value">'.
809
                    checkExtension('apcu', get_lang('Yes'), get_lang('No'), true, 'apc.enabled').'</td>
810
            </tr>
811
            <tr>
812
                <td class="requirements-item">
813
                    <a href="http://php.net/manual/en/book.iconv.php" target="_blank">Iconv</a> '.get_lang('Support').' ('.get_lang('Optional').')</td>
814
                <td class="requirements-value">'.
815
                    checkExtension('iconv', get_lang('Yes'), get_lang('No'), true).'</td>
816
            </tr>
817
            <tr>
818
                <td class="requirements-item">
819
                        <a href="http://php.net/manual/en/book.ldap.php" target="_blank">LDAP</a> '.get_lang('Support').' ('.get_lang('Optional').')</td>
820
                <td class="requirements-value">'.
821
                checkExtension('ldap', get_lang('Yes'), get_lang('LDAP Extension not available'), true).'</td>
822
            </tr>
823
            <tr>
824
                <td class="requirements-item">
825
                    <a href="http://xapian.org/" target="_blank">Xapian</a> '.get_lang('Support').' ('.get_lang('Optional').')</td>
826
                <td class="requirements-value">'.
827
                    checkExtension('xapian', get_lang('Yes'), get_lang('No'), true).'</td>
828
            </tr>
829
        </table>';
830
    echo '</div>';
831
832
    // RECOMMENDED SETTINGS
833
    // Note: these are the settings for Joomla, does this also apply for Chamilo?
834
    // Note: also add upload_max_filesize here so that large uploads are possible
835
    echo '<h4 class="install-subtitle">'.get_lang('(recommended) settings').'</h4>';
836
    echo '<div class="install-requirement">'.get_lang('(recommended) settingsInfo').'</div>';
837
    echo '<div class="table-responsive">';
838
    echo '<table class="table table-bordered table-sm">
839
            <tr>
840
                <th>'.get_lang('Setting').'</th>
841
                <th>'.get_lang('(recommended)').'</th>
842
                <th>'.get_lang('Currently').'</th>
843
            </tr>
844
            <tr>
845
                <td class="requirements-item">
846
                <a href="http://php.net/manual/ref.errorfunc.php#ini.display-errors">Display Errors</a></td>
847
                <td class="requirements-recommended">'.Display::label('OFF', 'success').'</td>
848
                <td class="requirements-value">'.checkPhpSetting('display_errors', 'OFF').'</td>
849
            </tr>
850
            <tr>
851
                <td class="requirements-item">
852
                <a href="http://php.net/manual/ini.core.php#ini.file-uploads">File Uploads</a></td>
853
                <td class="requirements-recommended">'.Display::label('ON', 'success').'</td>
854
                <td class="requirements-value">'.checkPhpSetting('file_uploads', 'ON').'</td>
855
            </tr>
856
            <tr>
857
                <td class="requirements-item">
858
                <a href="http://php.net/manual/ref.session.php#ini.session.auto-start">Session auto start</a></td>
859
                <td class="requirements-recommended">'.Display::label('OFF', 'success').'</td>
860
                <td class="requirements-value">'.checkPhpSetting('session.auto_start', 'OFF').'</td>
861
            </tr>
862
            <tr>
863
                <td class="requirements-item">
864
                <a href="http://php.net/manual/ini.core.php#ini.short-open-tag">Short Open Tag</a></td>
865
                <td class="requirements-recommended">'.Display::label('OFF', 'success').'</td>
866
                <td class="requirements-value">'.checkPhpSetting('short_open_tag', 'OFF').'</td>
867
            </tr>
868
            <tr>
869
                <td class="requirements-item">
870
                    <a href="http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-httponly">Cookie HTTP Only</a></td>
871
                <td class="requirements-recommended">'.
872
                    Display::label('ON', 'success').'</td>
873
                <td class="requirements-value">'.checkPhpSetting('session.cookie_httponly', 'ON').'</td>
874
            </tr>
875
            <tr>
876
                <td class="requirements-item">
877
                    <a href="http://php.net/manual/ini.core.php#ini.upload-max-filesize">Maximum upload file size</a></td>
878
                <td class="requirements-recommended">'.
879
                    Display::label('>= '.REQUIRED_MIN_UPLOAD_MAX_FILESIZE.'M', 'success').'</td>
880
                <td class="requirements-value">'.compare_setting_values(ini_get('upload_max_filesize'), REQUIRED_MIN_UPLOAD_MAX_FILESIZE).'</td>
881
            </tr>
882
            <tr>
883
                <td class="requirements-item">
884
                    <a href="http://php.net/manual/ini.core.php#ini.post-max-size">Maximum post size</a></td>
885
                <td class="requirements-recommended">'.
886
                Display::label('>= '.REQUIRED_MIN_POST_MAX_SIZE.'M', 'success').'</td>
887
                <td class="requirements-value">'.compare_setting_values(ini_get('post_max_size'), REQUIRED_MIN_POST_MAX_SIZE).'</td>
888
            </tr>
889
            <tr>
890
                <td class="requirements-item">
891
                    <a href="http://www.php.net/manual/en/ini.core.php#ini.memory-limit">Memory Limit</a></td>
892
                <td class="requirements-recommended">'.
893
                    Display::label('>= '.REQUIRED_MIN_MEMORY_LIMIT.'M', 'success').'</td>
894
                <td class="requirements-value">'.compare_setting_values($originalMemoryLimit, REQUIRED_MIN_MEMORY_LIMIT).'</td>
895
            </tr>
896
          </table>';
897
    echo '</div>';
898
899
    // DIRECTORY AND FILE PERMISSIONS
900
    echo '<h4 class="install-subtitle">'.get_lang('Directory and files permissions').'</h4>';
901
    echo '<div class="install-requirement">'.get_lang('Directory and files permissionsInfo').'</div>';
902
    echo '<div class="table-responsive">';
903
904
    $_SESSION['permissions_for_new_directories'] = $_setting['permissions_for_new_directories'] = $dir_perm_verified;
905
    $_SESSION['permissions_for_new_files'] = $_setting['permissions_for_new_files'] = $fil_perm_verified;
906
907
    $dir_perm = Display::label('0'.decoct($dir_perm_verified), 'info');
908
    $file_perm = Display::label('0'.decoct($fil_perm_verified), 'info');
909
910
    $oldConf = '';
911
    if (file_exists(api_get_path(SYS_CODE_PATH).'inc/conf/configuration.php')) {
912
        $oldConf = '<tr>
913
            <td class="requirements-item">'.api_get_path(SYS_CODE_PATH).'inc/conf</td>
914
            <td class="requirements-value">'.check_writable(api_get_path(SYS_CODE_PATH).'inc/conf').'</td>
915
        </tr>';
916
    }
917
    $basePath = api_get_path(SYMFONY_SYS_PATH);
918
    echo '<table class="table table-bordered table-sm">
919
            '.$oldConf.'
920
            <tr>
921
                <td class="requirements-item">'.$basePath.'var/</td>
922
                <td class="requirements-value">'.check_writable($basePath.'var').'</td>
923
            </tr>
924
            <tr>
925
                <td class="requirements-item">'.$basePath.'.env.local</td>
926
                <td class="requirements-value">'.checkCanCreateFile($basePath.'.env.local').'</td>
927
            </tr>
928
            <tr>
929
                <td class="requirements-item">'.$basePath.'config/</td>
930
                <td class="requirements-value">'.check_writable($basePath.'config').'</td>
931
            </tr>
932
            <tr>
933
                <td class="requirements-item">'.get_lang('Permissions for new directories').'</td>
934
                <td class="requirements-value">'.$dir_perm.' </td>
935
            </tr>
936
            <tr>
937
                <td class="requirements-item">'.get_lang('Permissions for new files').'</td>
938
                <td class="requirements-value">'.$file_perm.' </td>
939
            </tr>
940
        </table>';
941
    echo '</div>';
942
943
    if ('update' === $installType && (empty($updatePath) || $badUpdatePath)) {
944
        if ($badUpdatePath) {
945
            echo '<div class="alert alert-warning">';
946
            echo get_lang('Error');
947
            echo '<br />';
948
            echo 'Chamilo '.implode('|', $upgradeFromVersion).' '.get_lang('has not been found in that directory').'</div>';
949
        } else {
950
            echo '<br />';
951
        } ?>
952
            <div class="row">
953
                <div class="col-md-12">
954
                    <p><?php echo get_lang('Old version\'s root path'); ?>:
955
                        <input
956
                            type="text"
957
                            name="updatePath" size="50"
958
                            value="<?php echo ($badUpdatePath && !empty($updatePath)) ? htmlentities($updatePath) : ''; ?>" />
959
                    </p>
960
                    <p>
961
                        <div class="btn-group">
962
                            <button type="submit" class="btn btn-secondary" name="step1" value="<?php echo get_lang('Back'); ?>" >
963
                                <em class="fa fa-backward"> <?php echo get_lang('Back'); ?></em>
964
                            </button>
965
                            <input type="hidden" name="is_executable" id="is_executable" value="-" />
966
                            <button
967
                                type="submit"
968
                                class="btn btn-success"
969
                                name="<?php echo isset($_POST['step2_update_6']) ? 'step2_update_6' : 'step2_update_8'; ?>"
970
                                value="<?php echo get_lang('Next'); ?> &gt;" >
971
                                <em class="fa fa-forward"> </em> <?php echo get_lang('Next'); ?>
972
                            </button>
973
                        </div>
974
                    </p>
975
                </div>
976
            </div>
977
        <?php
978
    } else {
979
        $error = false;
980
        // First, attempt to set writing permissions if we don't have them yet
981
        //$perm = api_get_permissions_for_new_directories();
982
        $perm = octdec('0777');
983
        //$perm_file = api_get_permissions_for_new_files();
984
        $perm_file = octdec('0666');
985
        $notWritable = [];
986
987
        $checked_writable = api_get_path(SYS_PUBLIC_PATH);
988
        if (!is_writable($checked_writable)) {
989
            $notWritable[] = $checked_writable;
990
            @chmod($checked_writable, $perm);
991
        }
992
993
        if (false == $course_test_was_created) {
994
            error_log('Installer: Could not create test course - Make sure permissions are fine.');
995
            $error = true;
996
        }
997
998
        $checked_writable = api_get_path(CONFIGURATION_PATH).'configuration.php';
999
        if (file_exists($checked_writable) && !is_writable($checked_writable)) {
1000
            $notWritable[] = $checked_writable;
1001
            @chmod($checked_writable, $perm_file);
1002
        }
1003
1004
        // Second, if this fails, report an error
1005
        //--> The user would have to adjust the permissions manually
1006
        if (count($notWritable) > 0) {
1007
            error_log('Installer: At least one needed directory or file is not writeable');
1008
            $error = true; ?>
1009
            <div class="text-danger">
1010
                <h3 class="text-center"><?php echo get_lang('Warning !'); ?></h3>
1011
                <p>
1012
                    <?php printf(get_lang('Some files or folders don\'t have writing permission. To be able to install Chamilo you should first change their permissions (using CHMOD). Please read the %s installation guide %s'), '<a href="../../documentation/installation_guide.html" target="blank">', '</a>'); ?>
1013
                </p>
1014
            </div>
1015
            <?php
1016
            echo '<ul>';
1017
            foreach ($notWritable as $value) {
1018
                echo '<li class="text-danger">'.$value.'</li>';
1019
            }
1020
            echo '</ul>';
1021
        } elseif (file_exists(api_get_path(CONFIGURATION_PATH).'configuration.php')) {
1022
            // Check wether a Chamilo configuration file already exists.
1023
            echo '<div class="alert alert-warning"><h4><center>';
1024
            echo get_lang('Warning !ExistingLMSInstallationDetected');
1025
            echo '</center></h4></div>';
1026
        }
1027
1028
        $deprecated = [
1029
            api_get_path(SYS_CODE_PATH).'exercice/',
1030
            api_get_path(SYS_CODE_PATH).'newscorm/',
1031
            api_get_path(SYS_PLUGIN_PATH).'ticket/',
1032
            api_get_path(SYS_PLUGIN_PATH).'skype/',
1033
        ];
1034
        $deprecatedToRemove = [];
1035
        foreach ($deprecated as $deprecatedDirectory) {
1036
            if (!is_dir($deprecatedDirectory)) {
1037
                continue;
1038
            }
1039
            $deprecatedToRemove[] = $deprecatedDirectory;
1040
        }
1041
1042
        if (count($deprecatedToRemove) > 0) {
1043
            ?>
1044
            <p class="text-danger"><?php echo get_lang('Warning !ForDeprecatedDirectoriesForUpgrade'); ?></p>
1045
            <ul>
1046
                <?php foreach ($deprecatedToRemove as $deprecatedDirectory) {
1047
                ?>
1048
                    <li class="text-danger"><?php echo $deprecatedDirectory; ?></li>
1049
                <?php
1050
            } ?>
1051
            </ul>
1052
            <?php
1053
        }
1054
1055
        // And now display the choice buttons (go back or install)?>
1056
        <p align="center" style="padding-top:15px">
1057
            <button
1058
                type="submit"
1059
                name="step1"
1060
                class="btn btn-default"
1061
                onclick="javascript: window.location='index.php'; return false;"
1062
                value="<?php echo get_lang('Previous'); ?>" >
1063
                <em class="fa fa-backward"> </em> <?php echo get_lang('Previous'); ?>
1064
            </button>
1065
            <button
1066
                type="submit" name="step2_install"
1067
                class="btn btn-success"
1068
                value="<?php echo get_lang('New installation'); ?>" <?php if ($error) {
1069
            echo 'disabled="disabled"';
1070
        } ?> >
1071
                <em class="fa fa-forward"> </em> <?php echo get_lang('New installation'); ?>
1072
            </button>
1073
            <input type="hidden" name="is_executable" id="is_executable" value="-" />
1074
            <button
1075
                type="submit"
1076
                class="btn btn-default" <?php echo !$error ?: 'disabled="disabled"'; ?>
1077
                name="step2_update_8"
1078
                value="Upgrade from Chamilo 1.11.x">
1079
                <em class="fa fa-forward" aria-hidden="true"></em>
1080
                <?php echo get_lang('Upgrade Chamilo LMS version'); ?>
1081
            </button>
1082
            </p>
1083
        <?php
1084
    }
1085
}
1086
1087
/**
1088
 * Displays the license (GNU GPL) as step 2, with
1089
 * - an "I accept" button named step3 to proceed to step 3;
1090
 * - a "Back" button named step1 to go back to the first step.
1091
 */
1092
function display_license_agreement()
1093
{
1094
    echo '<div class="RequirementHeading"><h2>'.display_step_sequence().get_lang('Licence').'</h2>';
1095
    echo '<p>'.get_lang('Chamilo is free software distributed under the GNU General Public licence (GPL).').'</p>';
1096
    echo '<p><a href="../../documentation/license.html" target="_blank">'.get_lang('Printable version').'</a></p>';
1097
    $license = api_htmlentities(@file_get_contents(api_get_path(SYMFONY_SYS_PATH).'public/documentation/license.txt'));
1098
    echo '</div>';
1099
1100
    echo '<div class="form-group">
1101
        <pre style="overflow: auto; height: 200px; margin-top: 5px;">
1102
            '.$license.'
1103
        </pre>
1104
    </div>
1105
    <div class="form-group form-check">
1106
        <input type="checkbox" name="accept" id="accept_licence" value="1">
1107
        <label for="accept_licence">'.get_lang('I Accept').'</label>
1108
    </div>
1109
    <div class="row">
1110
        <div class="col-md-12">
1111
            <p class="alert alert-info">'.
1112
            get_lang('The images and media galleries of Chamilo use images from Nuvola, Crystal Clear and Tango icon galleries. Other images and media like diagrams and Flash animations are borrowed from Wikimedia and Ali Pakdel\'s and Denis Hoa\'s courses with their agreement and released under BY-SA Creative Commons license. You may find the license details at <a href="http://creativecommons.org/licenses/by-sa/3.0/">the CC website</a>, where a link to the full text of the license is provided at the bottom of the page.').'
1113
            </p>
1114
        </div>
1115
    </div>
1116
    <!-- Contact information form -->
1117
    <div class="section-parameters">
1118
        <a href="javascript://" class = "advanced_parameters" >
1119
        <span id="img_plus_and_minus">&nbsp;<i class="fa fa-eye" aria-hidden="true"></i>&nbsp;'.get_lang('Contact information').'</span>
1120
        </a>
1121
    </div>
1122
    <div id="id_contact_form" style="display:block">
1123
        <div class="normal-message">'.get_lang('Contact informationDescription').'</div>
1124
        <div id="contact_registration">
1125
            <p>'.get_contact_registration_form().'</p><br />
1126
        </div>
1127
    </div>
1128
    <div class="text-center">
1129
    <button type="submit" class="btn btn-default" name="step1" value="&lt; '.get_lang('Previous').'" >
1130
        <em class="fa fa-backward"> </em> '.get_lang('Previous').'
1131
    </button>
1132
    <input type="hidden" name="is_executable" id="is_executable" value="-" />
1133
    <button
1134
        type="submit"
1135
        id="license-next"
1136
        class="btn btn-success" name="step3"
1137
        onclick="javascript:if(!document.getElementById(\'accept_licence\').checked) { alert(\''.get_lang('You must accept the licence').'\');return false;}"
1138
        value="'.get_lang('Next').' &gt;">
1139
        <em class="fa fa-forward"> </em>'.get_lang('Next').'
1140
    </button>
1141
    </div>';
1142
}
1143
1144
/**
1145
 * Get contact registration form.
1146
 */
1147
function get_contact_registration_form()
1148
{
1149
    return '
1150
    <div class="form-horizontal">
1151
        <div class="panel panel-default">
1152
        <div class="panel-body">
1153
        <div id="div_sent_information"></div>
1154
        <div class="form-group row">
1155
                <label class="col-sm-3">
1156
                <span class="form_required">*</span>'.get_lang('Name').'</label>
1157
                <div class="col-sm-9">
1158
                    <input id="person_name" class="form-control" type="text" name="person_name" size="30" />
1159
                </div>
1160
        </div>
1161
        <div class="form-group row">
1162
            <label class="col-sm-3">
1163
            <span class="form_required">*</span>'.get_lang('e-mail').'</label>
1164
            <div class="col-sm-9">
1165
            <input id="person_email" class="form-control" type="text" name="person_email" size="30" /></div>
1166
        </div>
1167
        <div class="form-group row">
1168
                <label class="col-sm-3">
1169
                <span class="form_required">*</span>'.get_lang('Your company\'s name').'</label>
1170
                <div class="col-sm-9">
1171
                <input id="company_name" class="form-control" type="text" name="company_name" size="30" /></div>
1172
        </div>
1173
        <div class="form-group row">
1174
            <label class="col-sm-3"><span class="form_required">*</span>'.get_lang('Your company\'s activity').'</label>
1175
            <div class="col-sm-9">
1176
                <select class="form-control show-tick" name="company_activity" id="company_activity" >
1177
                    <option value="">--- '.get_lang('Select one').' ---</option>
1178
                    <Option value="Advertising/Marketing/PR">Advertising/Marketing/PR</Option>
1179
                    <Option value="Agriculture/Forestry">Agriculture/Forestry</Option>
1180
                    <Option value="Architecture">Architecture</Option>
1181
                    <Option value="Banking/Finance">Banking/Finance</Option>
1182
                    <Option value="Biotech/Pharmaceuticals">Biotech/Pharmaceuticals</Option>
1183
                    <Option value="Business Equipment">Business Equipment</Option>
1184
                    <Option value="Business Services">Business Services</Option>
1185
                    <Option value="Construction">Construction</Option>
1186
                    <Option value="Consulting/Research">Consulting/Research</Option>
1187
                    <Option value="Education">Education</Option>
1188
                    <Option value="Engineering">Engineering</Option>
1189
                    <Option value="Environmental">Environmental</Option>
1190
                    <Option value="Government">Government</Option>
1191
                    <Option value="Healthcare">Health Care</Option>
1192
                    <Option value="Hospitality/Lodging/Travel">Hospitality/Lodging/Travel</Option>
1193
                    <Option value="Insurance">Insurance</Option>
1194
                    <Option value="Legal">Legal</Option><Option value="Manufacturing">Manufacturing</Option>
1195
                    <Option value="Media/Entertainment">Media/Entertainment</Option>
1196
                    <Option value="Mortgage">Mortgage</Option>
1197
                    <Option value="Non-Profit">Non-Profit</Option>
1198
                    <Option value="Real Estate">Real Estate</Option>
1199
                    <Option value="Restaurant">Restaurant</Option>
1200
                    <Option value="Retail">Retail</Option>
1201
                    <Option value="Shipping/Transportation">Shipping/Transportation</Option>
1202
                    <Option value="Technology">Technology</Option>
1203
                    <Option value="Telecommunications">Telecommunications</Option>
1204
                    <Option value="Other">Other</Option>
1205
                </select>
1206
            </div>
1207
        </div>
1208
1209
        <div class="form-group row">
1210
            <label class="col-sm-3"><span class="form_required">*</span>'.get_lang('Your job\'s description').'</label>
1211
            <div class="col-sm-9">
1212
                <select class="form-control show-tick" name="person_role" id="person_role" >
1213
                    <option value="">--- '.get_lang('Select one').' ---</option>
1214
                    <Option value="Administration">Administration</Option>
1215
                    <Option value="CEO/President/ Owner">CEO/President/ Owner</Option>
1216
                    <Option value="CFO">CFO</Option><Option value="CIO/CTO">CIO/CTO</Option>
1217
                    <Option value="Consultant">Consultant</Option>
1218
                    <Option value="Customer Service">Customer Service</Option>
1219
                    <Option value="Engineer/Programmer">Engineer/Programmer</Option>
1220
                    <Option value="Facilities/Operations">Facilities/Operations</Option>
1221
                    <Option value="Finance/ Accounting Manager">Finance/ Accounting Manager</Option>
1222
                    <Option value="Finance/ Accounting Staff">Finance/ Accounting Staff</Option>
1223
                    <Option value="General Manager">General Manager</Option>
1224
                    <Option value="Human Resources">Human Resources</Option>
1225
                    <Option value="IS/IT Management">IS/IT Management</Option>
1226
                    <Option value="IS/ IT Staff">IS/ IT Staff</Option>
1227
                    <Option value="Marketing Manager">Marketing Manager</Option>
1228
                    <Option value="Marketing Staff">Marketing Staff</Option>
1229
                    <Option value="Partner/Principal">Partner/Principal</Option>
1230
                    <Option value="Purchasing Manager">Purchasing Manager</Option>
1231
                    <Option value="Sales/ Business Dev. Manager">Sales/ Business Dev. Manager</Option>
1232
                    <Option value="Sales/ Business Dev.">Sales/ Business Dev.</Option>
1233
                    <Option value="Vice President/Senior Manager">Vice President/Senior Manager</Option>
1234
                    <Option value="Other">Other</Option>
1235
                </select>
1236
            </div>
1237
        </div>
1238
1239
        <div class="form-group row">
1240
            <label class="col-sm-3">
1241
                <span class="form_required">*</span>'.get_lang('Your company\'s home country').'</label>
1242
            <div class="col-sm-9">'.get_countries_list_from_array(true).'</div>
1243
        </div>
1244
        <div class="form-group row">
1245
            <label class="col-sm-3">'.get_lang('Company city').'</label>
1246
            <div class="col-sm-9">
1247
                    <input type="text" class="form-control" id="company_city" name="company_city" size="30" />
1248
            </div>
1249
        </div>
1250
        <div class="form-group row">
1251
            <label class="col-sm-3">'.get_lang('Preferred contact language').'</label>
1252
            <div class="col-sm-9">
1253
                <select class="form-control show-tick" id="language" name="language">
1254
                    <option value="bulgarian">Bulgarian</option>
1255
                    <option value="indonesian">Bahasa Indonesia</option>
1256
                    <option value="bosnian">Bosanski</option>
1257
                    <option value="german">Deutsch</option>
1258
                    <option selected="selected" value="english">English</option>
1259
                    <option value="spanish">Spanish</option>
1260
                    <option value="french">Français</option>
1261
                    <option value="italian">Italian</option>
1262
                    <option value="hungarian">Magyar</option>
1263
                    <option value="dutch">Nederlands</option>
1264
                    <option value="brazilian">Português do Brasil</option>
1265
                    <option value="portuguese">Português europeu</option>
1266
                    <option value="slovenian">Slovenčina</option>
1267
                </select>
1268
            </div>
1269
        </div>
1270
1271
        <div class="form-group row">
1272
            <label class="col-sm-3">'.
1273
                get_lang('Do you have the power to take financial decisions on behalf of your company?').'</label>
1274
            <div class="col-sm-9">
1275
                <div class="radio">
1276
                    <label>
1277
                        <input type="radio" name="financial_decision" id="financial_decision1" value="1" checked /> '.
1278
                        get_lang('Yes').'
1279
                    </label>
1280
                </div>
1281
                <div class="radio">
1282
                    <label>
1283
                        <input type="radio" name="financial_decision" id="financial_decision2" value="0" /> '.
1284
                        get_lang('No').'
1285
                    </label>
1286
                </div>
1287
            </div>
1288
        </div>
1289
        <div class="clear"></div>
1290
        <div class="form-group row">
1291
            <div class="col-sm-3">&nbsp;</div>
1292
            <div class="col-sm-9">
1293
            <button
1294
                type="button"
1295
                class="btn btn-default"
1296
                onclick="javascript:send_contact_information();"
1297
                value="'.get_lang('Send information').'" >
1298
                <em class="fa fa-check"></em> '.get_lang('Send information').'
1299
            </button>
1300
            <span id="loader-button"></span></div>
1301
        </div>
1302
        <div class="form-group row">
1303
            <div class="col-sm-3">&nbsp;</div>
1304
            <div class="col-sm-9">
1305
                <span class="form_required">*</span><small>'.get_lang('Mandatory field').'</small>
1306
            </div>
1307
        </div></div></div>
1308
        </div>';
1309
}
1310
1311
/**
1312
 * Displays a parameter in a table row.
1313
 * Used by the display_database_settings_form function.
1314
 *
1315
 * @param   string  Type of install
1316
 * @param   string  Name of parameter
1317
 * @param   string  Field name (in the HTML form)
1318
 * @param   string  Field value
1319
 * @param   string  Extra notice (to show on the right side)
1320
 * @param   bool Whether to display in update mode
1321
 * @param   string  Additional attribute for the <tr> element
1322
 */
1323
function displayDatabaseParameter(
1324
    $installType,
1325
    $parameterName,
1326
    $formFieldName,
1327
    $parameterValue,
1328
    $extra_notice,
1329
    $displayWhenUpdate = true
1330
) {
1331
    echo "<dt class='col-sm-4'>$parameterName</dt>";
1332
    echo '<dd class="col-sm-8">';
1333
    if (INSTALL_TYPE_UPDATE == $installType && $displayWhenUpdate) {
1334
        echo '<input
1335
                type="hidden"
1336
                name="'.$formFieldName.'"
1337
                id="'.$formFieldName.'"
1338
                value="'.api_htmlentities($parameterValue).'" />'.$parameterValue;
1339
    } else {
1340
        $inputType = 'dbPassForm' === $formFieldName ? 'password' : 'text';
1341
        //Slightly limit the length of the database prefix to avoid having to cut down the databases names later on
1342
        $maxLength = 'dbPrefixForm' === $formFieldName ? '15' : MAX_FORM_FIELD_LENGTH;
1343
        if (INSTALL_TYPE_UPDATE == $installType) {
1344
            echo '<input
1345
                type="hidden" name="'.$formFieldName.'" id="'.$formFieldName.'"
1346
                value="'.api_htmlentities($parameterValue).'" />';
1347
            echo api_htmlentities($parameterValue);
1348
        } else {
1349
            echo '<input
1350
                        type="'.$inputType.'"
1351
                        class="form-control"
1352
                        size="'.DATABASE_FORM_FIELD_DISPLAY_LENGTH.'"
1353
                        maxlength="'.$maxLength.'"
1354
                        name="'.$formFieldName.'"
1355
                        id="'.$formFieldName.'"
1356
                        value="'.api_htmlentities($parameterValue).'" />
1357
                    '.$extra_notice.'
1358
                  ';
1359
        }
1360
    }
1361
    echo '</dd>';
1362
}
1363
1364
/**
1365
 * Displays step 3 - a form where the user can enter the installation settings
1366
 * regarding the databases - login and password, names, prefixes, single
1367
 * or multiple databases, tracking or not...
1368
 *
1369
 * @param string $installType
1370
 * @param string $dbHostForm
1371
 * @param string $dbUsernameForm
1372
 * @param string $dbPassForm
1373
 * @param string $dbNameForm
1374
 * @param int    $dbPortForm
1375
 * @param string $installationProfile
1376
 */
1377
function display_database_settings_form(
1378
    $installType,
1379
    $dbHostForm,
1380
    $dbUsernameForm,
1381
    $dbPassForm,
1382
    $dbNameForm,
1383
    $dbPortForm = 3306,
1384
    $installationProfile = ''
1385
) {
1386
    if ('update' === $installType) {
1387
        $dbHostForm = get_config_param('db_host');
1388
        $dbUsernameForm = get_config_param('db_user');
1389
        $dbPassForm = get_config_param('db_password');
1390
        $dbNameForm = get_config_param('main_database');
1391
        $dbPortForm = get_config_param('db_port');
1392
1393
        echo '<div class="RequirementHeading"><h2>'.display_step_sequence().get_lang('Database settings').'</h2></div>';
1394
        echo '<div class="RequirementContent">';
1395
        echo get_lang('The upgrade script will recover and update the Chamilo database(s). In order to do this, this script will use the databases and settings defined below. Because our software runs on a wide range of systems and because all of them might not have been tested, we strongly recommend you do a full backup of your databases before you proceed with the upgrade!');
1396
        echo '</div>';
1397
    } else {
1398
        echo '<div class="RequirementHeading"><h2>'.display_step_sequence().get_lang('Database settings').'</h2></div>';
1399
        echo '<div class="RequirementContent">';
1400
        echo get_lang('The install script will create (or use) the Chamilo database using the database name given here. Please make sure the user you give has the right to create the database by the name given here. If a database with this name exists, it will be overwritten. Please do not use the root user as the Chamilo database user. This can lead to serious security issues.');
1401
        echo '</div>';
1402
    }
1403
1404
    echo '
1405
        <div class="card">
1406
            <div class="card-body">
1407
            <dl class="row">
1408
                <dt class="col-sm-4">'.get_lang('Database Host').'</dt>';
1409
    if ('update' === $installType) {
1410
        echo '<dd class="col-sm-8">
1411
                <input
1412
                    type="hidden"
1413
                    name="dbHostForm" value="'.htmlentities($dbHostForm).'" />'.$dbHostForm.'
1414
                </dd>';
1415
    } else {
1416
        echo '<dd class="col-sm-8">
1417
                <input
1418
                    type="text"
1419
                    class="form-control"
1420
                    size="25"
1421
                    maxlength="50" name="dbHostForm" value="'.htmlentities($dbHostForm).'" />
1422
                    '.get_lang('ex.').'localhost
1423
            </dd>';
1424
    }
1425
1426
    echo '<dt class="col-sm-4">'.get_lang('Port').'</dt>';
1427
    if ('update' === $installType) {
1428
        echo '<dd class="col-sm-8">
1429
            <input
1430
                type="hidden"
1431
                name="dbPortForm" value="'.htmlentities($dbPortForm).'" />'.$dbPortForm.'
1432
            </dd>';
1433
    } else {
1434
        echo '
1435
        <dd class="col-sm-8">
1436
            <input
1437
            type="text"
1438
            class="form-control"
1439
            size="25"
1440
            maxlength="50" name="dbPortForm" value="'.htmlentities($dbPortForm).'" />
1441
            '.get_lang('ex.').' 3306
1442
        </dd>';
1443
    }
1444
    //database user username
1445
    $example_login = get_lang('ex.').' root';
1446
    displayDatabaseParameter(
1447
        $installType,
1448
        get_lang('Database Login'),
1449
        'dbUsernameForm',
1450
        $dbUsernameForm,
1451
        $example_login
1452
    );
1453
1454
    //database user password
1455
    $example_password = get_lang('ex.').' '.api_generate_password();
1456
    displayDatabaseParameter($installType, get_lang('Database Password'), 'dbPassForm', $dbPassForm, $example_password);
1457
    // Database Name fix replace weird chars
1458
    if (INSTALL_TYPE_UPDATE != $installType) {
1459
        $dbNameForm = str_replace(['-', '*', '$', ' ', '.'], '', $dbNameForm);
1460
    }
1461
    displayDatabaseParameter(
1462
        $installType,
1463
        get_lang('Database name'),
1464
        'dbNameForm',
1465
        $dbNameForm,
1466
        '&nbsp;',
1467
        null,
1468
        'id="optional_param1"'
1469
    );
1470
    echo '</div></div>';
1471
    if (INSTALL_TYPE_UPDATE != $installType) { ?>
1472
        <button type="submit" class="btn btn-primary" name="step3" value="step3">
1473
            <em class="fa fa-sync"> </em>
1474
            <?php echo get_lang('Check database connection'); ?>
1475
        </button>
1476
        <?php
1477
    }
1478
1479
    $databaseExistsText = '';
1480
    $manager = null;
1481
    try {
1482
        if ('update' === $installType) {
1483
            /** @var \Database $manager */
1484
            $manager = connectToDatabase(
1485
                $dbHostForm,
1486
                $dbUsernameForm,
1487
                $dbPassForm,
1488
                $dbNameForm,
1489
                $dbPortForm
1490
            );
1491
1492
            $connection = $manager->getConnection();
1493
            $connection->connect();
1494
            $schemaManager = $connection->getSchemaManager();
1495
1496
            // Test create/alter/drop table
1497
            $table = 'zXxTESTxX_'.mt_rand(0, 1000);
1498
            $sql = "CREATE TABLE $table (id INT AUTO_INCREMENT NOT NULL, name varchar(255), PRIMARY KEY(id))";
1499
            $connection->executeQuery($sql);
1500
            $tableCreationWorks = false;
1501
            $tableDropWorks = false;
1502
            if ($schemaManager->tablesExist($table)) {
1503
                $sql = "ALTER TABLE $table ADD COLUMN name2 varchar(140) ";
1504
                $connection->executeQuery($sql);
1505
                $schemaManager->dropTable($table);
1506
                $tableDropWorks = false === $schemaManager->tablesExist($table);
1507
            }
1508
        } else {
1509
            $manager = connectToDatabase(
1510
                $dbHostForm,
1511
                $dbUsernameForm,
1512
                $dbPassForm,
1513
                null,
1514
                $dbPortForm
1515
            );
1516
1517
            $schemaManager = $manager->getConnection()->getSchemaManager();
1518
            $databases = $schemaManager->listDatabases();
1519
            if (in_array($dbNameForm, $databases)) {
1520
                $databaseExistsText = '<div class="alert alert-warning">'.
1521
                get_lang('A database with the same name <b>already exists</b>. It will be <b>deleted</b>.').
1522
                    '</div>';
1523
            }
1524
        }
1525
    } catch (Exception $e) {
1526
        $databaseExistsText = $e->getMessage();
1527
        $manager = false;
1528
    }
1529
1530
    if ($manager && $manager->getConnection()->isConnected()) {
1531
        echo $databaseExistsText; ?>
1532
        <div id="db_status" class="alert alert-success">
1533
            Database host: <strong><?php echo $manager->getConnection()->getHost(); ?></strong><br/>
1534
            Database port: <strong><?php echo $manager->getConnection()->getPort(); ?></strong><br/>
1535
            Database driver: <strong><?php echo $manager->getConnection()->getDriver()->getName(); ?></strong><br/>
1536
            <?php
1537
                if ('update' === $installType) {
1538
                    echo get_lang('CreateTableWorks').' <strong>Ok</strong>';
1539
                    echo '<br/ >';
1540
                    echo get_lang('AlterTableWorks').' <strong>Ok</strong>';
1541
                    echo '<br/ >';
1542
                    echo get_lang('DropColumnWorks').' <strong>Ok</strong>';
1543
                } ?>
1544
        </div>
1545
    <?php
1546
    } else { ?>
1547
        <div id="db_status" class="alert alert-danger">
1548
            <p>
1549
                <?php echo get_lang('The database connection has failed. This is generally due to the wrong user, the wrong password or the wrong database prefix being set above. Please review these settings and try again.'); ?>
1550
            </p>
1551
            <code><?php echo $databaseExistsText; ?></code>
1552
        </div>
1553
    <?php } ?>
1554
1555
   <div class="btn-group" role="group">
1556
       <button type="submit" name="step2"
1557
               class="btn btn-secondary" value="&lt; <?php echo get_lang('Previous'); ?>" >
1558
           <em class="fa fa-backward"> </em> <?php echo get_lang('Previous'); ?>
1559
       </button>
1560
       <input type="hidden" name="is_executable" id="is_executable" value="-" />
1561
       <?php if ($manager) {
1562
        ?>
1563
           <button type="submit" class="btn btn-success" name="step4" value="<?php echo get_lang('Next'); ?> &gt;" >
1564
               <em class="fa fa-forward"> </em> <?php echo get_lang('Next'); ?>
1565
           </button>
1566
       <?php
1567
    } else {
1568
        ?>
1569
           <button
1570
                   disabled="disabled"
1571
                   type="submit" class="btn btn-success disabled" name="step4" value="<?php echo get_lang('Next'); ?> &gt;" >
1572
               <em class="fa fa-forward"> </em> <?php echo get_lang('Next'); ?>
1573
           </button>
1574
       <?php
1575
    } ?>
1576
   </div>
1577
    <?php
1578
}
1579
1580
/**
1581
 * Displays a parameter in a table row.
1582
 * Used by the display_configuration_settings_form function.
1583
 *
1584
 * @param string $installType
1585
 * @param string $parameterName
1586
 * @param string $formFieldName
1587
 * @param string $parameterValue
1588
 * @param string $displayWhenUpdate
1589
 *
1590
 * @return string
1591
 */
1592
function display_configuration_parameter(
1593
    $installType,
1594
    $parameterName,
1595
    $formFieldName,
1596
    $parameterValue,
1597
    $displayWhenUpdate = 'true'
1598
) {
1599
    $html = '<div class="form-group row">';
1600
    $html .= '<label class="col-sm-6 control-label">'.$parameterName.'</label>';
1601
    if (INSTALL_TYPE_UPDATE == $installType && $displayWhenUpdate) {
1602
        $html .= '<input
1603
            type="hidden"
1604
            name="'.$formFieldName.'"
1605
            value="'.api_htmlentities($parameterValue, ENT_QUOTES).'" />'.$parameterValue;
1606
    } else {
1607
        $html .= '<div class="col-sm-6">
1608
                    <input
1609
                        class="form-control"
1610
                        type="text"
1611
                        size="'.FORM_FIELD_DISPLAY_LENGTH.'"
1612
                        maxlength="'.MAX_FORM_FIELD_LENGTH.'"
1613
                        name="'.$formFieldName.'"
1614
                        value="'.api_htmlentities($parameterValue, ENT_QUOTES).'" />
1615
                    '.'</div>';
1616
    }
1617
    $html .= '</div>';
1618
1619
    return $html;
1620
}
1621
1622
/**
1623
 * Displays step 4 of the installation - configuration settings about Chamilo itself.
1624
 *
1625
 * @param string $installType
1626
 * @param string $urlForm
1627
 * @param string $languageForm
1628
 * @param string $emailForm
1629
 * @param string $adminFirstName
1630
 * @param string $adminLastName
1631
 * @param string $adminPhoneForm
1632
 * @param string $campusForm
1633
 * @param string $institutionForm
1634
 * @param string $institutionUrlForm
1635
 * @param string $encryptPassForm
1636
 * @param bool   $allowSelfReg
1637
 * @param bool   $allowSelfRegProf
1638
 * @param string $loginForm
1639
 * @param string $passForm
1640
 */
1641
function display_configuration_settings_form(
1642
    $installType,
1643
    $urlForm,
1644
    $languageForm,
1645
    $emailForm,
1646
    $adminFirstName,
1647
    $adminLastName,
1648
    $adminPhoneForm,
1649
    $campusForm,
1650
    $institutionForm,
1651
    $institutionUrlForm,
1652
    $encryptPassForm,
1653
    $allowSelfReg,
1654
    $allowSelfRegProf,
1655
    $loginForm,
1656
    $passForm
1657
) {
1658
    if ('update' !== $installType && empty($languageForm)) {
1659
        $languageForm = $_SESSION['install_language'];
1660
    }
1661
    echo '<div class="RequirementHeading">';
1662
    echo '<h2>'.display_step_sequence().get_lang('Configuration settings').'</h2>';
1663
    echo '</div>';
1664
1665
    // Parameter 1: administrator's login
1666
    if ('update' === $installType) {
1667
        $rootSys = get_config_param('root_web');
1668
        $html = display_configuration_parameter(
1669
            $installType,
1670
            get_lang('Chamilo URL'),
1671
            'loginForm',
1672
            $rootSys,
1673
            true
1674
        );
1675
        $rootSys = get_config_param('root_sys');
1676
        $html .= display_configuration_parameter(
1677
            $installType,
1678
            get_lang('Path'),
1679
            'loginForm',
1680
            $rootSys,
1681
            true
1682
        );
1683
        $systemVersion = get_config_param('system_version');
1684
        $html .= display_configuration_parameter(
1685
            $installType,
1686
            get_lang('Version'),
1687
            'loginForm',
1688
            $systemVersion,
1689
            true
1690
        );
1691
        echo Display::panel($html, get_lang('System'));
1692
    }
1693
1694
    $html = display_configuration_parameter(
1695
        $installType,
1696
        get_lang('Administrator login'),
1697
        'loginForm',
1698
        $loginForm,
1699
        'update' == $installType
1700
    );
1701
1702
    // Parameter 2: administrator's password
1703
    if ('update' !== $installType) {
1704
        $html .= display_configuration_parameter(
1705
            $installType,
1706
            get_lang('Administrator password (<font color="red">you may want to change this</font>)'),
1707
            'passForm',
1708
            $passForm,
1709
            false
1710
        );
1711
    }
1712
1713
    // Parameters 3 and 4: administrator's names
1714
    $html .= display_configuration_parameter(
1715
        $installType,
1716
        get_lang('Administrator first name'),
1717
        'adminFirstName',
1718
        $adminFirstName
1719
    );
1720
    $html .= display_configuration_parameter(
1721
        $installType,
1722
        get_lang('Administrator last name'),
1723
        'adminLastName',
1724
        $adminLastName
1725
    );
1726
1727
    // Parameter 3: administrator's email
1728
    $html .= display_configuration_parameter($installType, get_lang('Admin-mail'), 'emailForm', $emailForm);
1729
1730
    // Parameter 6: administrator's telephone
1731
    $html .= display_configuration_parameter(
1732
        $installType,
1733
        get_lang('Administrator telephone'),
1734
        'adminPhoneForm',
1735
        $adminPhoneForm
1736
    );
1737
    echo Display::panel($html, get_lang('Administrator'));
1738
1739
    // First parameter: language.
1740
    $html = '<div class="form-group row">';
1741
    $html .= '<label class="col-sm-6 control-label">'.get_lang('Language').'</label>';
1742
    if ('update' === $installType) {
1743
        $html .= '<input
1744
            type="hidden"
1745
            name="languageForm" value="'.api_htmlentities($languageForm, ENT_QUOTES).'" />'.
1746
            $languageForm;
1747
    } else {
1748
        $html .= '<div class="col-sm-6">';
1749
        $html .= display_language_selection_box('languageForm', $languageForm);
1750
        $html .= '</div>';
1751
    }
1752
    $html .= '</div>';
1753
1754
    // Second parameter: Chamilo URL
1755
    if ('install' === $installType) {
1756
        $html .= '<div class="form-group row">';
1757
        $html .= '<label class="col-sm-6 control-label">'.get_lang('Chamilo URL').'</label>';
1758
        $html .= '<div class="col-sm-6">';
1759
        $html .= '<input
1760
            class="form-control"
1761
            type="text" size="40"
1762
            required
1763
            maxlength="100" name="urlForm" value="'.api_htmlentities($urlForm, ENT_QUOTES).'" />';
1764
        $html .= '</div>';
1765
1766
        $html .= '</div>';
1767
    }
1768
1769
    // Parameter 9: campus name
1770
    $html .= display_configuration_parameter(
1771
        $installType,
1772
        get_lang('Your portal name'),
1773
        'campusForm',
1774
        $campusForm
1775
    );
1776
1777
    // Parameter 10: institute (short) name
1778
    $html .= display_configuration_parameter(
1779
        $installType,
1780
        get_lang('Your company short name'),
1781
        'institutionForm',
1782
        $institutionForm
1783
    );
1784
1785
    // Parameter 11: institute (short) name
1786
    $html .= display_configuration_parameter(
1787
        $installType,
1788
        get_lang('URL of this company'),
1789
        'institutionUrlForm',
1790
        $institutionUrlForm
1791
    );
1792
1793
    $html .= '<div class="form-group row">
1794
            <label class="col-sm-6 control-label">'.get_lang('Encryption method').'</label>
1795
        <div class="col-sm-6">';
1796
    if ('update' === $installType) {
1797
        $html .= '<input type="hidden" name="encryptPassForm" value="'.$encryptPassForm.'" />'.$encryptPassForm;
1798
    } else {
1799
        $html .= '<div class="checkbox">
1800
                    <label>
1801
                        <input
1802
                            type="radio"
1803
                            name="encryptPassForm"
1804
                            value="bcrypt"
1805
                            id="encryptPass1" '.('bcrypt' === $encryptPassForm ? 'checked="checked" ' : '').'/> bcrypt
1806
                    </label>';
1807
1808
        $html .= '<label>
1809
                        <input
1810
                            type="radio"
1811
                            name="encryptPassForm"
1812
                            value="sha1"
1813
                            id="encryptPass1" '.('sha1' === $encryptPassForm ? 'checked="checked" ' : '').'/> sha1
1814
                    </label>';
1815
1816
        $html .= '<label>
1817
                        <input type="radio"
1818
                            name="encryptPassForm"
1819
                            value="md5"
1820
                            id="encryptPass0" '.('md5' === $encryptPassForm ? 'checked="checked" ' : '').'/> md5
1821
                    </label>';
1822
1823
        $html .= '<label>
1824
                        <input
1825
                            type="radio"
1826
                            name="encryptPassForm"
1827
                            value="none"
1828
                            id="encryptPass2" '.
1829
                            ('none' === $encryptPassForm ? 'checked="checked" ' : '').'/>'.get_lang('none').'
1830
                    </label>';
1831
        $html .= '</div>';
1832
    }
1833
    $html .= '</div></div>';
1834
1835
    $html .= '<div class="form-group row">
1836
            <label class="col-sm-6 control-label">'.get_lang('Allow self-registration').'</label>
1837
            <div class="col-sm-6">';
1838
    if ('update' === $installType) {
1839
        if ('true' === $allowSelfReg) {
1840
            $label = get_lang('Yes');
1841
        } elseif ('false' === $allowSelfReg) {
1842
            $label = get_lang('No');
1843
        } else {
1844
            $label = get_lang('After approval');
1845
        }
1846
        $html .= '<input type="hidden" name="allowSelfReg" value="'.$allowSelfReg.'" />'.$label;
1847
    } else {
1848
        $html .= '<div class="control-group">';
1849
        $html .= '<label class="checkbox-inline">
1850
                    <input type="radio"
1851
                        name="allowSelfReg" value="true"
1852
                        id="allowSelfReg1" '.('true' == $allowSelfReg ? 'checked="checked" ' : '').' /> '.get_lang('Yes').'
1853
                  </label>';
1854
        $html .= '<label class="checkbox-inline">
1855
                    <input
1856
                        type="radio"
1857
                        name="allowSelfReg"
1858
                        value="false"
1859
                        id="allowSelfReg0" '.('false' == $allowSelfReg ? '' : 'checked="checked" ').' /> '.get_lang('No').'
1860
                </label>';
1861
        $html .= '<label class="checkbox-inline">
1862
                    <input
1863
                        type="radio"
1864
                        name="allowSelfReg"
1865
                        value="approval"
1866
                        id="allowSelfReg2" '.('approval' == $allowSelfReg ? '' : 'checked="checked" ').' /> '.get_lang('After approval').'
1867
                </label>';
1868
        $html .= '</div>';
1869
    }
1870
    $html .= '</div>';
1871
    $html .= '</div>';
1872
1873
    $html .= '<div class="form-group row">';
1874
    $html .= '<label class="col-sm-6 control-label">'.get_lang('Allow self-registrationProf').'</label>
1875
                <div class="col-sm-6">';
1876
    if ('update' === $installType) {
1877
        if ('true' === $allowSelfRegProf) {
1878
            $label = get_lang('Yes');
1879
        } else {
1880
            $label = get_lang('No');
1881
        }
1882
        $html .= '<input type="hidden" name="allowSelfRegProf" value="'.$allowSelfRegProf.'" />'.$label;
1883
    } else {
1884
        $html .= '<div class="control-group">
1885
                <label class="checkbox-inline">
1886
                    <input
1887
                        type="radio"
1888
                        name="allowSelfRegProf" value="1"
1889
                        id="allowSelfRegProf1" '.($allowSelfRegProf ? 'checked="checked" ' : '').'/>
1890
                '.get_lang('Yes').'
1891
                </label>';
1892
        $html .= '<label class="checkbox-inline">
1893
                    <input
1894
                        type="radio" name="allowSelfRegProf" value="0"
1895
                        id="allowSelfRegProf0" '.($allowSelfRegProf ? '' : 'checked="checked" ').' />
1896
                   '.get_lang('No').'
1897
                </label>';
1898
        $html .= '</div>';
1899
    }
1900
    $html .= '</div>
1901
    </div>';
1902
    echo Display::panel($html, get_lang('Portal')); ?>
1903
    <div class='btn-group'>
1904
        <button
1905
            type="submit"
1906
            class="btn btn-secondary "
1907
            name="step3" value="&lt; <?php echo get_lang('Previous'); ?>" >
1908
                <em class="fa fa-backward"> </em> <?php echo get_lang('Previous'); ?>
1909
        </button>
1910
        <input type="hidden" name="is_executable" id="is_executable" value="-" />
1911
        <button class="btn btn-success" type="submit" name="step5">
1912
            <em class="fa fa-forward"> </em> <?php echo get_lang('Next'); ?>
1913
        </button>
1914
    </div>
1915
    <?php
1916
}
1917
1918
/**
1919
 * After installation is completed (step 6), this message is displayed.
1920
 */
1921
function display_after_install_message()
1922
{
1923
    $container = Container::$container;
1924
    $trans = $container->get('translator');
1925
    $html = '<div class="RequirementContent">'.
1926
    $trans->trans(
1927
        'When you enter your portal for the first time, the best way to understand it is to create a course with the \'Create course\' link in the menu and play around a little.').'</div>';
1928
    $html .= '<div class="alert alert-warning">';
1929
    $html .= '<strong>'.$trans->trans('Security advice').'</strong>';
1930
    $html .= ': ';
1931
    $html .= sprintf($trans->trans(
1932
        'To protect your site, make the whole %s directory read-only (chmod -R 0555 on Linux) and delete the %s directory.'), 'var/config/', 'main/install/');
1933
    $html .= '</div></form>
1934
    <br />
1935
    <a class="btn btn-success btn-block" href="../../">
1936
        '.$trans->trans('Go to your newly created portal.').'
1937
    </a>';
1938
1939
    return $html;
1940
}
1941
1942
/**
1943
 * This function return countries list from array (hardcoded).
1944
 *
1945
 * @param bool $combo (Optional) True for returning countries list with select html
1946
 *
1947
 * @return array|string countries list
1948
 */
1949
function get_countries_list_from_array($combo = false)
1950
{
1951
    $a_countries = [
1952
        'Afghanistan', 'Albania', 'Algeria', 'Andorra', 'Angola', 'Antigua and Barbuda', 'Argentina', 'Armenia', 'Australia', 'Austria', 'Azerbaijan',
1953
        'Bahamas', 'Bahrain', 'Bangladesh', 'Barbados', 'Belarus', 'Belgium', 'Belize', 'Benin', 'Bhutan', 'Bolivia', 'Bosnia and Herzegovina', 'Botswana', 'Brazil', 'Brunei', 'Bulgaria', 'Burkina Faso', 'Burundi',
1954
        'Cambodia', 'Cameroon', 'Canada', 'Cape Verde', 'Central African Republic', 'Chad', 'Chile', 'China', 'Colombi', 'Comoros', 'Congo (Brazzaville)', 'Congo', 'Costa Rica', "Cote d'Ivoire", 'Croatia', 'Cuba', 'Cyprus', 'Czech Republic',
1955
        'Denmark', 'Djibouti', 'Dominica', 'Dominican Republic',
1956
        'East Timor (Timor Timur)', 'Ecuador', 'Egypt', 'El Salvador', 'Equatorial Guinea', 'Eritrea', 'Estonia', 'Ethiopia',
1957
        'Fiji', 'Finland', 'France',
1958
        'Gabon', 'Gambia, The', 'Georgia', 'Germany', 'Ghana', 'Greece', 'Grenada', 'Guatemala', 'Guinea', 'Guinea-Bissau', 'Guyana',
1959
        'Haiti', 'Honduras', 'Hungary',
1960
        'Iceland', 'India', 'Indonesia', 'Iran', 'Iraq', 'Ireland', 'Israel', 'Italy',
1961
        'Jamaica', 'Japan', 'Jordan',
1962
        'Kazakhstan', 'Kenya', 'Kiribati', 'Korea, North', 'Korea, South', 'Kuwait', 'Kyrgyzstan',
1963
        'Laos', 'Latvia', 'Lebanon', 'Lesotho', 'Liberia', 'Libya', 'Liechtenstein', 'Lithuania', 'Luxembourg',
1964
        'Macedonia', 'Madagascar', 'Malawi', 'Malaysia', 'Maldives', 'Mali', 'Malta', 'Marshall Islands', 'Mauritania', 'Mauritius', 'Mexico', 'Micronesia', 'Moldova', 'Monaco', 'Mongolia', 'Morocco', 'Mozambique', 'Myanmar',
1965
        'Namibia', 'Nauru', 'Nepa', 'Netherlands', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 'Norway',
1966
        'Oman',
1967
        'Pakistan', 'Palau', 'Panama', 'Papua New Guinea', 'Paraguay', 'Peru', 'Philippines', 'Poland', 'Portugal',
1968
        'Qatar',
1969
        'Romania', 'Russia', 'Rwanda',
1970
        'Saint Kitts and Nevis', 'Saint Lucia', 'Saint Vincent', 'Samoa', 'San Marino', 'Sao Tome and Principe', 'Saudi Arabia', 'Senegal', 'Serbia and Montenegro', 'Seychelles', 'Sierra Leone', 'Singapore', 'Slovakia', 'Slovenia', 'Solomon Islands', 'Somalia', 'South Africa', 'Spain', 'Sri Lanka', 'Sudan', 'Suriname', 'Swaziland', 'Sweden', 'Switzerland', 'Syria',
1971
        'Taiwan', 'Tajikistan', 'Tanzania', 'Thailand', 'Togo', 'Tonga', 'Trinidad and Tobago', 'Tunisia', 'Turkey', 'Turkmenistan', 'Tuvalu',
1972
        'Uganda', 'Ukraine', 'United Arab Emirates', 'United Kingdom', 'United States', 'Uruguay', 'Uzbekistan',
1973
        'Vanuatu', 'Vatican City', 'Venezuela', 'Vietnam',
1974
        'Yemen',
1975
        'Zambia', 'Zimbabwe',
1976
    ];
1977
    if ($combo) {
1978
        $country_select = '<select class="form-control show-tick" id="country" name="country">';
1979
        $country_select .= '<option value="">--- '.get_lang('Select one').' ---</option>';
1980
        foreach ($a_countries as $country) {
1981
            $country_select .= '<option value="'.$country.'">'.$country.'</option>';
1982
        }
1983
        $country_select .= '</select>';
1984
1985
        return $country_select;
1986
    }
1987
1988
    return $a_countries;
1989
}
1990
1991
/**
1992
 * Lock settings that can't be changed in other portals.
1993
 */
1994
function lockSettings()
1995
{
1996
    $settings = api_get_locked_settings();
1997
    $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
1998
    foreach ($settings as $setting) {
1999
        $sql = "UPDATE $table SET access_url_locked = 1 WHERE variable  = '$setting'";
2000
        Database::query($sql);
2001
    }
2002
}
2003
2004
/**
2005
 * Update dir values.
2006
 */
2007
function updateDirAndFilesPermissions()
2008
{
2009
    $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
2010
    $permissions_for_new_directories = isset($_SESSION['permissions_for_new_directories']) ? $_SESSION['permissions_for_new_directories'] : 0770;
2011
    $permissions_for_new_files = isset($_SESSION['permissions_for_new_files']) ? $_SESSION['permissions_for_new_files'] : 0660;
2012
    // use decoct() to store as string
2013
    Database::update(
2014
        $table,
2015
        ['selected_value' => '0'.decoct($permissions_for_new_directories)],
2016
        ['variable = ?' => 'permissions_for_new_directories']
2017
    );
2018
2019
    Database::update(
2020
        $table,
2021
        ['selected_value' => '0'.decoct($permissions_for_new_files)],
2022
        ['variable = ?' => 'permissions_for_new_files']
2023
    );
2024
2025
    if (isset($_SESSION['permissions_for_new_directories'])) {
2026
        unset($_SESSION['permissions_for_new_directories']);
2027
    }
2028
2029
    if (isset($_SESSION['permissions_for_new_files'])) {
2030
        unset($_SESSION['permissions_for_new_files']);
2031
    }
2032
}
2033
2034
/**
2035
 * @param $current_value
2036
 * @param $wanted_value
2037
 *
2038
 * @return string
2039
 */
2040
function compare_setting_values($current_value, $wanted_value)
2041
{
2042
    $current_value_string = $current_value;
2043
    $current_value = (float) $current_value;
2044
    $wanted_value = (float) $wanted_value;
2045
2046
    if ($current_value >= $wanted_value) {
2047
        return Display::label($current_value_string, 'success');
2048
    }
2049
2050
    return Display::label($current_value_string, 'important');
2051
}
2052
2053
/**
2054
 * Save settings values.
2055
 *
2056
 * @param string $organizationName
2057
 * @param string $organizationUrl
2058
 * @param string $siteName
2059
 * @param string $adminEmail
2060
 * @param string $adminLastName
2061
 * @param string $adminFirstName
2062
 * @param string $language
2063
 * @param string $allowRegistration
2064
 * @param string $allowTeacherSelfRegistration
2065
 * @param string $installationProfile          The name of an installation profile file in main/install/profiles/
2066
 */
2067
function installSettings(
2068
    $organizationName,
2069
    $organizationUrl,
2070
    $siteName,
2071
    $adminEmail,
2072
    $adminLastName,
2073
    $adminFirstName,
2074
    $language,
2075
    $allowRegistration,
2076
    $allowTeacherSelfRegistration,
2077
    $installationProfile = ''
2078
) {
2079
    error_log('installSettings');
2080
    $allowTeacherSelfRegistration = $allowTeacherSelfRegistration ? 'true' : 'false';
2081
2082
    $settings = [
2083
        'institution' => $organizationName,
2084
        'institution_url' => $organizationUrl,
2085
        'site_name' => $siteName,
2086
        'administrator_email' => $adminEmail,
2087
        'administrator_surname' => $adminLastName,
2088
        'administrator_name' => $adminFirstName,
2089
        'platform_language' => $language,
2090
        'allow_registration' => $allowRegistration,
2091
        'allow_registration_as_teacher' => $allowTeacherSelfRegistration,
2092
    ];
2093
2094
    foreach ($settings as $variable => $value) {
2095
        $sql = "UPDATE settings_current
2096
                SET selected_value = '$value'
2097
                WHERE variable = '$variable'";
2098
        Database::query($sql);
2099
    }
2100
    installProfileSettings($installationProfile);
2101
}
2102
2103
/**
2104
 * Executes DB changes based in the classes defined in
2105
 * /src/CoreBundle/Migrations/Schema/V200/*.
2106
 *
2107
 * @return bool
2108
 */
2109
function migrate(EntityManager $manager)
2110
{
2111
    $debug = true;
2112
    $connection = $manager->getConnection();
2113
    $to = null; // if $to == null then schema will be migrated to latest version
2114
2115
    // Loading migration configuration.
2116
    $config = new PhpFile('./migrations.php');
2117
    $dependency = DependencyFactory::fromConnection($config, new ExistingConnection($connection));
2118
2119
    // Check if old "version" table exists from 1.11.x, use new version.
2120
    $schema = $manager->getConnection()->getSchemaManager();
2121
    $dropOldVersionTable = false;
2122
    if ($schema->tablesExist('version')) {
2123
        $columns = $schema->listTableColumns('version');
2124
        if (in_array('id', array_keys($columns), true)) {
2125
            $dropOldVersionTable = true;
2126
        }
2127
    }
2128
2129
    if ($dropOldVersionTable) {
2130
        error_log('Drop version table');
2131
        $schema->dropTable('version');
2132
    }
2133
2134
    // Creates "version" table.
2135
    $dependency->getMetadataStorage()->ensureInitialized();
2136
2137
    // Loading migrations.
2138
    $migratorConfigurationFactory = $dependency->getConsoleInputMigratorConfigurationFactory();
2139
    $result = '';
2140
    $input = new Symfony\Component\Console\Input\StringInput($result);
2141
    $migratorConfiguration = $migratorConfigurationFactory->getMigratorConfiguration($input);
2142
    $migrator = $dependency->getMigrator();
2143
    $planCalculator = $dependency->getMigrationPlanCalculator();
2144
    $migrations = $planCalculator->getMigrations();
2145
    $lastVersion = $migrations->getLast();
2146
2147
    $plan = $dependency->getMigrationPlanCalculator()->getPlanUntilVersion($lastVersion->getVersion());
2148
2149
    foreach ($plan->getItems() as $item) {
2150
        error_log("Version to be executed: ".$item->getVersion());
2151
        $item->getMigration()->setEntityManager($manager);
2152
        $item->getMigration()->setContainer(Container::$container);
2153
    }
2154
2155
    // Execute migration!!
2156
    /** @var $migratedVersions */
2157
    $versions = $migrator->migrate($plan, $migratorConfiguration);
2158
2159
    if ($debug) {
2160
        /** @var Query[] $queries */
2161
        $versionCounter = 1;
2162
        foreach ($versions as $version => $queries) {
2163
            $total = count($queries);
2164
            echo '----------------------------------------------<br />';
2165
            $message = "VERSION: $version";
2166
            echo "$message<br/>";
2167
            error_log('-------------------------------------');
2168
            error_log($message);
2169
            $counter = 1;
2170
            foreach ($queries as $query) {
2171
                $sql = $query->getStatement();
2172
                echo "<code>$sql</code><br>";
2173
                error_log("$counter/$total : $sql");
2174
                $counter++;
2175
            }
2176
            $versionCounter++;
2177
        }
2178
        echo '<br/>DONE!<br />';
2179
        error_log('DONE!');
2180
    }
2181
2182
    return true;
2183
}
2184
2185
/**
2186
 * @param string $distFile
2187
 * @param string $envFile
2188
 * @param array  $params
2189
 */
2190
function updateEnvFile($distFile, $envFile, $params)
2191
{
2192
    $requirements = [
2193
        'DATABASE_HOST',
2194
        'DATABASE_PORT',
2195
        'DATABASE_NAME',
2196
        'DATABASE_USER',
2197
        'DATABASE_PASSWORD',
2198
        'APP_INSTALLED',
2199
        'APP_ENCRYPT_METHOD',
2200
    ];
2201
2202
    foreach ($requirements as $requirement) {
2203
        if (!isset($params['{{'.$requirement.'}}'])) {
2204
            throw new \Exception("The parameter $requirement is needed in order to edit the .env.local file");
2205
        }
2206
    }
2207
2208
    $contents = file_get_contents($distFile);
2209
    $contents = str_replace(array_keys($params), array_values($params), $contents);
2210
    file_put_contents($envFile, $contents);
2211
    error_log("File env saved here: $envFile");
2212
}
2213
2214
function installTools($container, $manager, $upgrade = false)
2215
{
2216
    error_log('installTools');
2217
    // Install course tools (table "tool")
2218
    /** @var ToolChain $toolChain */
2219
    $toolChain = $container->get(ToolChain::class);
2220
    $toolChain->createTools($manager);
2221
}
2222
2223
/**
2224
 * @param SymfonyContainer $container
2225
 * @param bool             $upgrade
2226
 */
2227
function installSchemas($container, $upgrade = false)
2228
{
2229
    error_log('installSchemas');
2230
    $settingsManager = $container->get('chamilo.settings.manager');
2231
2232
    $urlRepo = $container->get(AccessUrlRepository::class);
2233
    $accessUrl = $urlRepo->find(1);
2234
    if (null === $accessUrl) {
2235
        $em = Database::getManager();
2236
2237
        // Creating AccessUrl.
2238
        $accessUrl = new AccessUrl();
2239
        $accessUrl
2240
            ->setUrl(AccessUrl::DEFAULT_ACCESS_URL)
2241
            ->setDescription('')
2242
            ->setActive(1)
2243
            ->setCreatedBy(1)
2244
        ;
2245
        $em->persist($accessUrl);
2246
        $em->flush();
2247
2248
        error_log('AccessUrl created');
2249
    }
2250
2251
    if ($upgrade) {
2252
        error_log('Upgrade settings');
2253
        $settingsManager->updateSchemas($accessUrl);
2254
    } else {
2255
        error_log('Install settings');
2256
        // Installing schemas (filling settings_current table)
2257
        $settingsManager->installSchemas($accessUrl);
2258
    }
2259
}
2260
2261
/**
2262
 * @param SymfonyContainer $container
2263
 */
2264
function upgradeWithContainer($container)
2265
{
2266
    Container::setContainer($container);
2267
    Container::setLegacyServices($container, false);
2268
    error_log('setLegacyServices');
2269
    $manager = Database::getManager();
2270
2271
    /** @var GroupRepository $repo */
2272
    $repo = $container->get(GroupRepository::class);
2273
    $repo->createDefaultGroups();
2274
2275
    // @todo check if adminId = 1
2276
    installTools($container, $manager, true);
2277
    installSchemas($container, true);
2278
}
2279
2280
/**
2281
 * After the schema was created (table creation), the function adds
2282
 * admin/platform information.
2283
 *
2284
 * @param \Psr\Container\ContainerInterface $container
2285
 * @param string                            $sysPath
2286
 * @param string                            $encryptPassForm
2287
 * @param string                            $passForm
2288
 * @param string                            $adminLastName
2289
 * @param string                            $adminFirstName
2290
 * @param string                            $loginForm
2291
 * @param string                            $emailForm
2292
 * @param string                            $adminPhoneForm
2293
 * @param string                            $languageForm
2294
 * @param string                            $institutionForm
2295
 * @param string                            $institutionUrlForm
2296
 * @param string                            $siteName
2297
 * @param string                            $allowSelfReg
2298
 * @param string                            $allowSelfRegProf
2299
 * @param string                            $installationProfile Installation profile, if any was provided
2300
 */
2301
function finishInstallationWithContainer(
2302
    $container,
2303
    $sysPath,
2304
    $encryptPassForm,
2305
    $passForm,
2306
    $adminLastName,
2307
    $adminFirstName,
2308
    $loginForm,
2309
    $emailForm,
2310
    $adminPhoneForm,
2311
    $languageForm,
2312
    $institutionForm,
2313
    $institutionUrlForm,
2314
    $siteName,
2315
    $allowSelfReg,
2316
    $allowSelfRegProf,
2317
    $installationProfile = ''
2318
) {
2319
    error_log('finishInstallationWithContainer');
2320
    Container::setContainer($container);
2321
    Container::setLegacyServices($container, false);
2322
    error_log('setLegacyServices');
2323
2324
    //UserManager::setPasswordEncryption($encryptPassForm);
2325
    $timezone = api_get_timezone();
2326
2327
    error_log('user creation - admin');
2328
2329
    $repo = Container::getUserRepository();
2330
    /** @var User $admin */
2331
    $admin = $repo->findOneBy(['username' => 'admin']);
2332
2333
    $admin
2334
        ->setLastname($adminFirstName)
2335
        ->setFirstname($adminLastName)
2336
        ->setUsername($loginForm)
2337
        ->setStatus(1)
2338
        ->setPlainPassword($passForm)
2339
        ->setEmail($emailForm)
2340
        ->setOfficialCode('ADMIN')
2341
        ->setAuthSource(PLATFORM_AUTH_SOURCE)
2342
        ->setPhone($adminPhoneForm)
2343
        ->setLocale($languageForm)
2344
        ->setTimezone($timezone)
2345
    ;
2346
2347
    $repo->updateUser($admin);
2348
2349
    $repo = Container::getUserRepository();
2350
    $repo->updateUser($admin);
2351
2352
    // Set default language
2353
    Database::update(
2354
        Database::get_main_table(TABLE_MAIN_LANGUAGE),
2355
        ['available' => 1],
2356
        ['english_name = ?' => $languageForm]
2357
    );
2358
2359
    // Install settings
2360
    installSettings(
2361
        $institutionForm,
2362
        $institutionUrlForm,
2363
        $siteName,
2364
        $emailForm,
2365
        $adminLastName,
2366
        $adminFirstName,
2367
        $languageForm,
2368
        $allowSelfReg,
2369
        $allowSelfRegProf,
2370
        $installationProfile
2371
    );
2372
    lockSettings();
2373
    updateDirAndFilesPermissions();
2374
}
2375
2376
/**
2377
 * Update settings based on installation profile defined in a JSON file.
2378
 *
2379
 * @param string $installationProfile The name of the JSON file in main/install/profiles/ folder
2380
 *
2381
 * @return bool false on failure (no bad consequences anyway, just ignoring profile)
2382
 */
2383
function installProfileSettings($installationProfile = '')
2384
{
2385
    error_log('installProfileSettings');
2386
    if (empty($installationProfile)) {
2387
        return false;
2388
    }
2389
    $jsonPath = api_get_path(SYS_PATH).'main/install/profiles/'.$installationProfile.'.json';
2390
    // Make sure the path to the profile is not hacked
2391
    if (!Security::check_abs_path($jsonPath, api_get_path(SYS_PATH).'main/install/profiles/')) {
2392
        return false;
2393
    }
2394
    if (!is_file($jsonPath)) {
2395
        return false;
2396
    }
2397
    if (!is_readable($jsonPath)) {
2398
        return false;
2399
    }
2400
    if (!function_exists('json_decode')) {
2401
        // The php-json extension is not available. Ignore profile.
2402
        return false;
2403
    }
2404
    $json = file_get_contents($jsonPath);
2405
    $params = json_decode($json);
2406
    if (false === $params or null === $params) {
2407
        return false;
2408
    }
2409
    $settings = $params->params;
2410
    if (!empty($params->parent)) {
2411
        installProfileSettings($params->parent);
2412
    }
2413
2414
    $tblSettings = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
2415
2416
    foreach ($settings as $id => $param) {
2417
        $conditions = ['variable = ? ' => $param->variable];
2418
2419
        if (!empty($param->subkey)) {
2420
            $conditions['AND subkey = ? '] = $param->subkey;
2421
        }
2422
2423
        Database::update(
2424
            $tblSettings,
2425
            ['selected_value' => $param->selected_value],
2426
            $conditions
2427
        );
2428
    }
2429
2430
    return true;
2431
}
2432
2433
/**
2434
 * Quick function to remove a directory with its subdirectories.
2435
 *
2436
 * @param $dir
2437
 */
2438
function rrmdir($dir)
2439
{
2440
    if (is_dir($dir)) {
2441
        $objects = scandir($dir);
2442
        foreach ($objects as $object) {
2443
            if ('.' != $object && '..' != $object) {
2444
                if ('dir' == filetype($dir.'/'.$object)) {
2445
                    @rrmdir($dir.'/'.$object);
2446
                } else {
2447
                    @unlink($dir.'/'.$object);
2448
                }
2449
            }
2450
        }
2451
        reset($objects);
2452
        rmdir($dir);
2453
    }
2454
}
2455
2456
/**
2457
 * Control the different steps of the migration through a big switch.
2458
 *
2459
 * @param string        $fromVersion
2460
 * @param EntityManager $manager
2461
 * @param bool          $processFiles
2462
 *
2463
 * @return bool Always returns true except if the process is broken
2464
 */
2465
function migrateSwitch($fromVersion, $manager, $processFiles = true)
2466
{
2467
    error_log('-----------------------------------------');
2468
    error_log('Starting migration process from '.$fromVersion.' ('.date('Y-m-d H:i:s').')');
2469
    //echo '<a class="btn btn-secondary" href="javascript:void(0)" id="details_button">'.get_lang('Details').'</a><br />';
2470
    //echo '<div id="details" style="display:none">';
2471
    $connection = $manager->getConnection();
2472
2473
    switch ($fromVersion) {
2474
        case '1.11.0':
2475
        case '1.11.1':
2476
        case '1.11.2':
2477
        case '1.11.4':
2478
        case '1.11.6':
2479
        case '1.11.8':
2480
        case '1.11.10':
2481
        case '1.11.12':
2482
        case '1.11.14':
2483
            $start = time();
2484
            // Migrate using the migration files located in:
2485
            // /srv/http/chamilo2/src/CoreBundle/Migrations/Schema/V200
2486
            $result = migrate($manager);
2487
            error_log('-----------------------------------------');
2488
2489
            if ($result) {
2490
                error_log('Migrations files were executed ('.date('Y-m-d H:i:s').')');
2491
                $sql = "UPDATE settings_current SET selected_value = '2.0.0'
2492
                        WHERE variable = 'chamilo_database_version'";
2493
                $connection->executeQuery($sql);
2494
                if ($processFiles) {
2495
                    error_log('Update config files');
2496
                    include __DIR__.'/update-files-1.11.0-2.0.0.inc.php';
2497
                    // Only updates the configuration.inc.php with the new version
2498
                    //include __DIR__.'/update-configuration.inc.php';
2499
                }
2500
                $finish = time();
2501
                $total = round(($finish - $start) / 60);
2502
                error_log('Database migration finished:  ('.date('Y-m-d H:i:s').') took '.$total.' minutes');
2503
            } else {
2504
                error_log('There was an error during running migrations. Check error.log');
2505
                exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
2506
            }
2507
            break;
2508
        default:
2509
            break;
2510
    }
2511
2512
    //echo '</div>';
2513
2514
    return true;
2515
}
2516
2517
/**
2518
 * @return string
2519
 */
2520
function generateRandomToken()
2521
{
2522
    return hash('sha1', uniqid(mt_rand(), true));
2523
}
2524
2525
/**
2526
 * This function checks if the given file can be created or overwritten.
2527
 *
2528
 * @param string $file Full path to a file
2529
 *
2530
 * @return string An HTML coloured label showing success or failure
2531
 */
2532
function checkCanCreateFile($file)
2533
{
2534
    if (file_exists($file)) {
2535
        if (is_writable($file)) {
2536
            return Display::label(get_lang('Writable'), 'success');
2537
        } else {
2538
            return Display::label(get_lang('Not writable'), 'important');
2539
        }
2540
    } else {
2541
        $write = @file_put_contents($file, '');
2542
        if (false !== $write) {
2543
            unlink($file);
2544
2545
            return Display::label(get_lang('Writable'), 'success');
2546
        } else {
2547
            return Display::label(get_lang('Not writable'), 'important');
2548
        }
2549
    }
2550
}
2551