Passed
Push — master ( efc6d8...ea9271 )
by Julito
11:57
created

updateWithContainer()   A

Complexity

Conditions 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nop 1
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Entity\AccessUrl;
5
use Chamilo\CoreBundle\Entity\ExtraField;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, ExtraField. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
6
use Chamilo\CoreBundle\Framework\Container;
7
use Chamilo\TicketBundle\Entity\Category as TicketCategory;
8
use Chamilo\TicketBundle\Entity\Priority as TicketPriority;
9
use Chamilo\TicketBundle\Entity\Project as TicketProject;
10
use Doctrine\ORM\EntityManager;
11
use Sonata\PageBundle\Entity\PageManager;
12
use Symfony\Component\DependencyInjection\Container as SymfonyContainer;
13
14
/**
15
 * Chamilo LMS
16
 * This file contains functions used by the install and upgrade scripts.
17
 *
18
 * Ideas for future additions:
19
 * - a function get_old_version_settings to retrieve the config file settings
20
 *   of older versions before upgrading.
21
 */
22
23
/* CONSTANTS */
24
define('SYSTEM_CONFIG_FILENAME', 'configuration.dist.php');
25
26
/**
27
 * This function detects whether the system has been already installed.
28
 * It should be used for prevention from second running the installation
29
 * script and as a result - destroying a production system.
30
 *
31
 * @return bool The detected result;
32
 *
33
 * @author Ivan Tcholakov, 2010;
34
 */
35
function isAlreadyInstalledSystem()
36
{
37
    global $new_version, $_configuration;
38
39
    if (empty($new_version)) {
40
        return true; // Must be initialized.
41
    }
42
43
    $current_config_file = api_get_path(CONFIGURATION_PATH).'configuration.php';
44
    if (!file_exists($current_config_file)) {
45
        return false; // Configuration file does not exist, install the system.
46
    }
47
    require $current_config_file;
48
49
    $current_version = null;
50
    if (isset($_configuration['system_version'])) {
51
        $current_version = trim($_configuration['system_version']);
52
    }
53
54
    // If the current version is old, upgrading is assumed, the installer goes ahead.
55
    return empty($current_version) ? false : version_compare($current_version, $new_version, '>=');
56
}
57
58
/**
59
 * This function checks if a php extension exists or not and returns an HTML status string.
60
 *
61
 * @param string $extensionName Name of the PHP extension to be checked
62
 * @param string $returnSuccess Text to show when extension is available (defaults to 'Yes')
63
 * @param string $returnFailure Text to show when extension is available (defaults to 'No')
64
 * @param bool   $optional      Whether this extension is optional (then show unavailable text in orange rather than red)
65
 * @param string $enabledTerm   If this string is not null, then use to check if the corresponding parameter is = 1.
66
 *                              If not, mention it's present but not enabled. For example, for opcache, this should be 'opcache.enable'
67
 *
68
 * @return string HTML string reporting the status of this extension. Language-aware.
69
 *
70
 * @author  Christophe Gesch??
71
 * @author  Patrick Cool <[email protected]>, Ghent University
72
 * @author  Yannick Warnier <[email protected]>
73
 */
74
function checkExtension(
75
    $extensionName,
76
    $returnSuccess = 'Yes',
77
    $returnFailure = 'No',
78
    $optional = false,
79
    $enabledTerm = ''
80
) {
81
    if (extension_loaded($extensionName)) {
82
        if (!empty($enabledTerm)) {
83
            $isEnabled = ini_get($enabledTerm);
84
            if ($isEnabled == '1') {
85
                return Display::label($returnSuccess, 'success');
86
            } else {
87
                if ($optional) {
88
                    return Display::label(get_lang('ExtensionInstalledButNotEnabled'), 'warning');
89
                } else {
90
                    return Display::label(get_lang('ExtensionInstalledButNotEnabled'), 'important');
91
                }
92
            }
93
        } else {
94
            return Display::label($returnSuccess, 'success');
95
        }
96
    } else {
97
        if ($optional) {
98
            return Display::label($returnFailure, 'warning');
99
        } else {
100
            return Display::label($returnFailure, 'important');
101
        }
102
    }
103
}
104
105
/**
106
 * This function checks whether a php setting matches the recommended value.
107
 *
108
 * @param string $phpSetting       A PHP setting to check
109
 * @param string $recommendedValue A recommended value to show on screen
110
 * @param mixed  $returnSuccess    What to show on success
111
 * @param mixed  $returnFailure    What to show on failure
112
 *
113
 * @return string A label to show
114
 *
115
 * @author Patrick Cool <[email protected]>, Ghent University
116
 */
117
function checkPhpSetting(
118
    $phpSetting,
119
    $recommendedValue,
120
    $returnSuccess = false,
121
    $returnFailure = false
0 ignored issues
show
Unused Code introduced by
The parameter $returnFailure is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

121
    /** @scrutinizer ignore-unused */ $returnFailure = false

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
122
) {
123
    $currentPhpValue = getPhpSetting($phpSetting);
124
    if ($currentPhpValue == $recommendedValue) {
125
        return Display::label($currentPhpValue.' '.$returnSuccess, 'success');
0 ignored issues
show
Bug introduced by
Are you sure $returnSuccess of type false|mixed can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

125
        return Display::label($currentPhpValue.' './** @scrutinizer ignore-type */ $returnSuccess, 'success');
Loading history...
126
    } else {
127
        return Display::label($currentPhpValue.' '.$returnSuccess, 'important');
128
    }
129
}
130
131
/**
132
 * This function return the value of a php.ini setting if not "" or if exists,
133
 * otherwise return false.
134
 *
135
 * @param string $phpSetting The name of a PHP setting
136
 *
137
 * @return mixed The value of the setting, or false if not found
138
 */
139
function checkPhpSettingExists($phpSetting)
140
{
141
    if (ini_get($phpSetting) != "") {
142
        return ini_get($phpSetting);
143
    }
144
145
    return false;
146
}
147
148
/**
149
 * Check if the current url is the same root_web when the multiple_access_url is enabled.
150
 *
151
 * @return bool
152
 */
153
function checkAccessUrl()
154
{
155
    if (api_get_configuration_value('multiple_access_urls') !== true) {
156
        return true;
157
    }
158
159
    $currentWebPath = api_get_path(WEB_PATH);
160
    $rootWeb = api_get_configuration_value('root_web');
161
162
    return $currentWebPath === $rootWeb;
163
}
164
165
/**
166
 * Returns a textual value ('ON' or 'OFF') based on a requester 2-state ini- configuration setting.
167
 *
168
 * @param string $val a php ini value
169
 *
170
 * @return bool ON or OFF
171
 *
172
 * @author Joomla <http://www.joomla.org>
173
 */
174
function getPhpSetting($val)
175
{
176
    $value = ini_get($val);
177
    switch ($val) {
178
        case 'display_errors':
179
            global $originalDisplayErrors;
180
            $value = $originalDisplayErrors;
181
            break;
182
    }
183
184
    return $value == '1' ? 'ON' : 'OFF';
0 ignored issues
show
Bug Best Practice introduced by
The expression return $value == '1' ? 'ON' : 'OFF' returns the type string which is incompatible with the documented return type boolean.
Loading history...
185
}
186
187
/**
188
 * This function returns a string "true" or "false" according to the passed parameter.
189
 *
190
 * @param int $var The variable to present as text
191
 *
192
 * @return string the string "true" or "false"
193
 *
194
 * @author Christophe Gesch??
195
 */
196
function trueFalse($var)
197
{
198
    return $var ? 'true' : 'false';
199
}
200
201
/**
202
 * Removes memory and time limits as much as possible.
203
 */
204
function remove_memory_and_time_limits()
205
{
206
    if (function_exists('ini_set')) {
207
        ini_set('memory_limit', -1);
208
        ini_set('max_execution_time', 0);
209
        error_log('Update-db script: memory_limit set to -1', 0);
210
        error_log('Update-db script: max_execution_time 0', 0);
211
    } else {
212
        error_log('Update-db script: could not change memory and time limits', 0);
213
    }
214
}
215
216
/**
217
 * Detects browser's language.
218
 *
219
 * @return string Returns a language identificator, i.e. 'english', 'spanish', ...
220
 *
221
 * @author Ivan Tcholakov, 2010
222
 */
223
function detect_browser_language()
224
{
225
    static $language_index = [
226
        'ar' => 'arabic',
227
        'ast' => 'asturian',
228
        'bg' => 'bulgarian',
229
        'bs' => 'bosnian',
230
        'ca' => 'catalan',
231
        'zh' => 'simpl_chinese',
232
        'zh-tw' => 'trad_chinese',
233
        'cs' => 'czech',
234
        'da' => 'danish',
235
        'prs' => 'dari',
236
        'de' => 'german',
237
        'el' => 'greek',
238
        'en' => 'english',
239
        'es' => 'spanish',
240
        'eo' => 'esperanto',
241
        'eu' => 'basque',
242
        'fa' => 'persian',
243
        'fr' => 'french',
244
        'fur' => 'friulian',
245
        'gl' => 'galician',
246
        'ka' => 'georgian',
247
        'hr' => 'croatian',
248
        'he' => 'hebrew',
249
        'hi' => 'hindi',
250
        'id' => 'indonesian',
251
        'it' => 'italian',
252
        'ko' => 'korean',
253
        'lv' => 'latvian',
254
        'lt' => 'lithuanian',
255
        'mk' => 'macedonian',
256
        'hu' => 'hungarian',
257
        'ms' => 'malay',
258
        'nl' => 'dutch',
259
        'ja' => 'japanese',
260
        'no' => 'norwegian',
261
        'oc' => 'occitan',
262
        'ps' => 'pashto',
263
        'pl' => 'polish',
264
        'pt' => 'portuguese',
265
        'pt-br' => 'brazilian',
266
        'ro' => 'romanian',
267
        'qu' => 'quechua_cusco',
268
        'ru' => 'russian',
269
        'sk' => 'slovak',
270
        'sl' => 'slovenian',
271
        'sr' => 'serbian',
272
        'fi' => 'finnish',
273
        'sv' => 'swedish',
274
        'th' => 'thai',
275
        'tr' => 'turkish',
276
        'uk' => 'ukrainian',
277
        'vi' => 'vietnamese',
278
        'sw' => 'swahili',
279
        'yo' => 'yoruba',
280
    ];
281
282
    $system_available_languages = get_language_folder_list();
283
    $accept_languages = strtolower(str_replace('_', '-', $_SERVER['HTTP_ACCEPT_LANGUAGE']));
284
    foreach ($language_index as $code => $language) {
285
        if (strpos($accept_languages, $code) === 0) {
286
            if (!empty($system_available_languages[$language])) {
287
                return $language;
288
            }
289
        }
290
    }
291
292
    $user_agent = strtolower(str_replace('_', '-', $_SERVER['HTTP_USER_AGENT']));
293
    foreach ($language_index as $code => $language) {
294
        if (@preg_match("/[\[\( ]{$code}[;,_\-\)]/", $user_agent)) {
295
            if (!empty($system_available_languages[$language])) {
296
                return $language;
297
            }
298
        }
299
    }
300
301
    return 'english';
302
}
303
304
/*      FILESYSTEM RELATED FUNCTIONS */
305
306
/**
307
 * This function checks if the given folder is writable.
308
 *
309
 * @param string $folder     Full path to a folder
310
 * @param bool   $suggestion Whether to show a suggestion or not
311
 *
312
 * @return string
313
 */
314
function check_writable($folder, $suggestion = false)
315
{
316
    if (is_writable($folder)) {
317
        return Display::label(get_lang('Writable'), 'success');
318
    } else {
319
        if ($suggestion) {
320
            return Display::label(get_lang('NotWritable'), 'info');
321
        } else {
322
            return Display::label(get_lang('NotWritable'), 'important');
323
        }
324
    }
325
}
326
327
/**
328
 * This function checks if the given folder is readable.
329
 *
330
 * @param string $folder     Full path to a folder
331
 * @param bool   $suggestion Whether to show a suggestion or not
332
 *
333
 * @return string
334
 */
335
function checkReadable($folder, $suggestion = false)
336
{
337
    if (is_readable($folder)) {
338
        return Display::label(get_lang('Readable'), 'success');
339
    } else {
340
        if ($suggestion) {
341
            return Display::label(get_lang('NotReadable'), 'info');
342
        } else {
343
            return Display::label(get_lang('NotReadable'), 'important');
344
        }
345
    }
346
}
347
348
/**
349
 * This function is similar to the core file() function, except that it
350
 * works with line endings in Windows (which is not the case of file()).
351
 *
352
 * @param string $filename
353
 *
354
 * @return array The lines of the file returned as an array
355
 */
356
function file_to_array($filename)
357
{
358
    if (!is_readable($filename) || is_dir($filename)) {
359
        return [];
360
    }
361
    $fp = fopen($filename, 'rb');
362
    $buffer = fread($fp, filesize($filename));
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fread() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

362
    $buffer = fread(/** @scrutinizer ignore-type */ $fp, filesize($filename));
Loading history...
363
    fclose($fp);
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

363
    fclose(/** @scrutinizer ignore-type */ $fp);
Loading history...
364
365
    return explode('<br />', nl2br($buffer));
366
}
367
368
/**
369
 * We assume this function is called from install scripts that reside inside the install folder.
370
 */
371
function set_file_folder_permissions()
372
{
373
    @chmod('.', 0755); //set permissions on install dir
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for chmod(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

373
    /** @scrutinizer ignore-unhandled */ @chmod('.', 0755); //set permissions on install dir

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
374
    @chmod('..', 0755); //set permissions on parent dir of install dir
375
}
376
377
/**
378
 * Write the main system config file.
379
 *
380
 * @param string $path Path to the config file
381
 */
382
function write_system_config_file($path)
383
{
384
    global $dbHostForm;
385
    global $dbPortForm;
386
    global $dbUsernameForm;
387
    global $dbPassForm;
388
    global $dbNameForm;
389
    global $urlForm;
390
    global $pathForm;
391
    global $urlAppendPath;
392
    global $languageForm;
393
    global $encryptPassForm;
394
    global $session_lifetime;
395
    global $new_version;
396
    global $new_version_stable;
397
398
    $root_sys = api_add_trailing_slash(str_replace('\\', '/', realpath($pathForm)));
399
    $content = file_get_contents(__DIR__.'/'.SYSTEM_CONFIG_FILENAME);
400
401
    $config['{DATE_GENERATED}'] = date('r');
0 ignored issues
show
Comprehensibility Best Practice introduced by
$config was never initialized. Although not strictly required by PHP, it is generally a good practice to add $config = array(); before regardless.
Loading history...
402
    $config['{DATABASE_HOST}'] = $dbHostForm;
403
    $config['{DATABASE_PORT}'] = $dbPortForm;
404
    $config['{DATABASE_USER}'] = $dbUsernameForm;
405
    $config['{DATABASE_PASSWORD}'] = $dbPassForm;
406
    $config['{DATABASE_MAIN}'] = $dbNameForm;
407
    $config['{ROOT_WEB}'] = $urlForm;
408
    $config['{ROOT_SYS}'] = $root_sys;
409
    $config['{URL_APPEND_PATH}'] = $urlAppendPath;
410
    $config['{PLATFORM_LANGUAGE}'] = $languageForm;
411
    $config['{SECURITY_KEY}'] = md5(uniqid(rand().time()));
412
    $config['{ENCRYPT_PASSWORD}'] = $encryptPassForm;
413
414
    $config['SESSION_LIFETIME'] = $session_lifetime;
415
    $config['{NEW_VERSION}'] = $new_version;
416
    $config['NEW_VERSION_STABLE'] = trueFalse($new_version_stable);
417
418
    foreach ($config as $key => $value) {
419
        $content = str_replace($key, $value, $content);
420
    }
421
    $fp = @fopen($path, 'w');
422
423
    if (!$fp) {
0 ignored issues
show
introduced by
$fp is of type resource|false, thus it always evaluated to false.
Loading history...
424
        echo '<strong>
425
                <font color="red">Your script doesn\'t have write access to the config directory</font></strong><br />
426
                <em>('.str_replace('\\', '/', realpath($path)).')</em><br /><br />
427
                You probably do not have write access on Chamilo root directory,
428
                i.e. you should <em>CHMOD 777</em> or <em>755</em> or <em>775</em>.<br /><br />
429
                Your problems can be related on two possible causes:<br />
430
                <ul>
431
                  <li>Permission problems.<br />Try initially with <em>chmod -R 777</em> and increase restrictions gradually.</li>
432
                  <li>PHP is running in <a href="http://www.php.net/manual/en/features.safe-mode.php" target="_blank">Safe-Mode</a>. 
433
                  If possible, try to switch it off.</li>
434
                </ul>
435
                <a href="http://forum.chamilo.org/" target="_blank">Read about this problem in Support Forum</a><br /><br />
436
                Please go back to step 5.
437
                <p><input type="submit" name="step5" value="&lt; Back" /></p>
438
                </td></tr></table></form></body></html>';
439
        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...
440
    }
441
442
    fwrite($fp, $content);
443
    fclose($fp);
444
}
445
446
/**
447
 * Returns a list of language directories.
448
 */
449
function get_language_folder_list()
450
{
451
    return [
452
        'ar' => 'arabic',
453
        'ast' => 'asturian',
454
        'bg' => 'bulgarian',
455
        'bs' => 'bosnian',
456
        'ca' => 'catalan',
457
        'zh' => 'simpl_chinese',
458
        'zh-tw' => 'trad_chinese',
459
        'cs' => 'czech',
460
        'da' => 'danish',
461
        'prs' => 'dari',
462
        'de' => 'german',
463
        'el' => 'greek',
464
        'en' => 'english',
465
        'es' => 'spanish',
466
        'eo' => 'esperanto',
467
        'eu' => 'basque',
468
        'fa' => 'persian',
469
        'fr' => 'french',
470
        'fur' => 'friulian',
471
        'gl' => 'galician',
472
        'ka' => 'georgian',
473
        'hr' => 'croatian',
474
        'he' => 'hebrew',
475
        'hi' => 'hindi',
476
        'id' => 'indonesian',
477
        'it' => 'italian',
478
        'ko' => 'korean',
479
        'lv' => 'latvian',
480
        'lt' => 'lithuanian',
481
        'mk' => 'macedonian',
482
        'hu' => 'hungarian',
483
        'ms' => 'malay',
484
        'nl' => 'dutch',
485
        'ja' => 'japanese',
486
        'no' => 'norwegian',
487
        'oc' => 'occitan',
488
        'ps' => 'pashto',
489
        'pl' => 'polish',
490
        'pt' => 'portuguese',
491
        'pt-br' => 'brazilian',
492
        'ro' => 'romanian',
493
        'qu' => 'quechua_cusco',
494
        'ru' => 'russian',
495
        'sk' => 'slovak',
496
        'sl' => 'slovenian',
497
        'sr' => 'serbian',
498
        'fi' => 'finnish',
499
        'sv' => 'swedish',
500
        'th' => 'thai',
501
        'tr' => 'turkish',
502
        'uk' => 'ukrainian',
503
        'vi' => 'vietnamese',
504
        'sw' => 'swahili',
505
        'yo' => 'yoruba',
506
    ];
507
}
508
509
/**
510
 * This function returns the value of a parameter from the configuration file.
511
 *
512
 * WARNING - this function relies heavily on global variables $updateFromConfigFile
513
 * and $configFile, and also changes these globals. This can be rewritten.
514
 *
515
 * @param string $param the parameter of which the value is returned
516
 * @param   string  If we want to give the path rather than take it from POST
517
 *
518
 * @return string the value of the parameter
519
 *
520
 * @author Olivier Brouckaert
521
 * @author Reworked by Ivan Tcholakov, 2010
522
 */
523
function get_config_param($param, $updatePath = '')
524
{
525
    global $configFile, $updateFromConfigFile;
526
527
    // Look if we already have the queried parameter.
528
    if (is_array($configFile) && isset($configFile[$param])) {
529
        return $configFile[$param];
530
    }
531
    if (empty($updatePath) && !empty($_POST['updatePath'])) {
532
        $updatePath = $_POST['updatePath'];
533
    }
534
535
    if (empty($updatePath)) {
536
        $updatePath = api_get_path(SYS_PATH);
537
    }
538
    $updatePath = api_add_trailing_slash(str_replace('\\', '/', realpath($updatePath)));
539
    $updateFromInstalledVersionFile = '';
540
541
    if (empty($updateFromConfigFile)) {
542
        // If update from previous install was requested,
543
        // try to recover config file from Chamilo 1.9.x
544
        if (file_exists($updatePath.'main/inc/conf/configuration.php')) {
545
            $updateFromConfigFile = 'main/inc/conf/configuration.php';
546
        } elseif (file_exists($updatePath.'app/config/configuration.php')) {
547
            $updateFromConfigFile = 'app/config/configuration.php';
548
        } else {
549
            // Give up recovering.
550
            //error_log('Chamilo Notice: Could not find previous config file at '.$updatePath.'main/inc/conf/configuration.php nor at '.$updatePath.'claroline/inc/conf/claro_main.conf.php in get_config_param(). Will start new config (in '.__FILE__.', line '.__LINE__.')', 0);
551
            return null;
552
        }
553
    }
554
555
    if (file_exists($updatePath.$updateFromConfigFile) &&
556
        !is_dir($updatePath.$updateFromConfigFile)
557
    ) {
558
        require $updatePath.$updateFromConfigFile;
559
        $config = new Zend\Config\Config($_configuration);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $_configuration does not exist. Did you maybe mean $config?
Loading history...
560
561
        return $config->get($param);
562
    }
563
564
    error_log('Config array could not be found in get_config_param()', 0);
565
566
    return null;
567
}
568
569
/*      DATABASE RELATED FUNCTIONS */
570
571
/**
572
 * Gets a configuration parameter from the database. Returns returns null on failure.
573
 *
574
 * @param string $param Name of param we want
575
 *
576
 * @return mixed The parameter value or null if not found
577
 */
578
function get_config_param_from_db($param = '')
579
{
580
    if (($res = Database::query("SELECT * FROM settings_current WHERE variable = '$param'")) !== false) {
581
        if (Database::num_rows($res) > 0) {
582
            $row = Database::fetch_array($res);
583
584
            return $row['selected_value'];
585
        }
586
    }
587
588
    return null;
589
}
590
591
/**
592
 * Connect to the database and returns the entity manager.
593
 *
594
 * @param string $dbHostForm     DB host
595
 * @param string $dbUsernameForm DB username
596
 * @param string $dbPassForm     DB password
597
 * @param string $dbNameForm     DB name
598
 * @param int    $dbPortForm     DB port
599
 *
600
 * @return Database
601
 */
602
function connectToDatabase(
603
    $dbHostForm,
604
    $dbUsernameForm,
605
    $dbPassForm,
606
    $dbNameForm,
607
    $dbPortForm = 3306
608
) {
609
    $dbParams = [
610
        'driver' => 'pdo_mysql',
611
        'host' => $dbHostForm,
612
        'port' => $dbPortForm,
613
        'user' => $dbUsernameForm,
614
        'password' => $dbPassForm,
615
        'dbname' => $dbNameForm,
616
    ];
617
618
    $database = new \Database();
619
    $database->connect($dbParams);
620
621
    return $database;
622
}
623
624
/*      DISPLAY FUNCTIONS */
625
626
/**
627
 * This function prints class=active_step $current_step=$param.
628
 *
629
 * @param int $param A step in the installer process
630
 *
631
 * @author Patrick Cool <[email protected]>, Ghent University
632
 */
633
function step_active($param)
634
{
635
    global $current_step;
636
    if ($param == $current_step) {
637
        echo 'class="current-step" ';
638
    }
639
}
640
641
/**
642
 * This function displays the Step X of Y -.
643
 *
644
 * @return string String that says 'Step X of Y' with the right values
645
 */
646
function display_step_sequence()
647
{
648
    global $current_step;
649
650
    return get_lang('Step'.$current_step).' &ndash; ';
651
}
652
653
/**
654
 * Displays a drop down box for selection the preferred language.
655
 */
656
function display_language_selection_box(
657
    $name = 'language_list',
658
    $default_language = 'english'
659
) {
660
    // Reading language list.
661
    $language_list = get_language_folder_list();
662
663
    // Sanity checks due to the possibility for customizations.
664
    if (!is_array($language_list) || empty($language_list)) {
665
        $language_list = ['en' => 'English'];
666
    }
667
668
    // Sorting again, if it is necessary.
669
    //asort($language_list);
670
671
    // More sanity checks.
672
    if (!array_key_exists($default_language, $language_list)) {
673
        if (array_key_exists('en', $language_list)) {
674
            $default_language = 'en';
675
        } else {
676
            $language_keys = array_keys($language_list);
677
            $default_language = $language_keys[0];
678
        }
679
    }
680
681
    // Displaying the box.
682
    $html = '';
683
    $html .= "\t\t<select class='selectpicker show-tick' name=\"$name\">\n";
684
    foreach ($language_list as $key => $value) {
685
        if ($key == $default_language) {
686
            $option_end = ' selected="selected">';
687
        } else {
688
            $option_end = '>';
689
        }
690
        $html .= "\t\t\t<option value=\"$key\"$option_end";
691
        $html .= $value;
692
        $html .= "</option>\n";
693
    }
694
    $html .= "\t\t</select>\n";
695
696
    return $html;
697
}
698
699
/**
700
 * This function displays a language dropdown box so that the installatioin
701
 * can be done in the language of the user.
702
 */
703
function display_language_selection()
704
{
705
    ?>
706
    <h2><?php get_lang('WelcomeToTheChamiloInstaller'); ?></h2>
707
    <div class="RequirementHeading">
708
        <h2><?php echo display_step_sequence(); ?>
709
            <?php echo get_lang('InstallationLanguage'); ?>
710
        </h2>
711
        <p><?php echo get_lang('PleaseSelectInstallationProcessLanguage'); ?>:</p>
712
        <form id="lang_form" method="post" action="<?php echo api_get_self(); ?>">
713
        <div class="form-group">
714
            <div class="col-sm-4">
715
                <?php echo display_language_selection_box('language_list', api_get_interface_language()); ?>
716
            </div>
717
            <div class="col-sm-6">
718
                <button type="submit" name="step1" class="btn btn-success" value="<?php echo get_lang('Next'); ?>">
719
                    <em class="fa fa-forward"> </em>
720
                    <?php echo get_lang('Next'); ?></button>
721
            </div>
722
        </div>
723
724
        <input type="hidden" name="is_executable" id="is_executable" value="-" />
725
        </form>
726
727
    </div>
728
    <div class="RequirementHeading">
729
        <?php echo get_lang('YourLanguageNotThereContactUs'); ?>
730
    </div>
731
<?php
732
}
733
734
/**
735
 * This function displays the requirements for installing Chamilo.
736
 *
737
 * @param string $installType
738
 * @param bool   $badUpdatePath
739
 * @param bool   $badUpdatePath
740
 * @param string $updatePath            The updatePath given (if given)
741
 * @param array  $update_from_version_8 The different subversions from version 1.9
742
 *
743
 * @author unknow
744
 * @author Patrick Cool <[email protected]>, Ghent University
745
 */
746
function display_requirements(
747
    $installType,
748
    $badUpdatePath,
749
    $updatePath = '',
750
    $update_from_version_8 = []
751
) {
752
    global $_setting, $originalMemoryLimit;
753
    echo '<div class="RequirementHeading"><h2>'.display_step_sequence().get_lang('Requirements')."</h2></div>";
754
    echo '<div class="RequirementText">';
755
    echo '<strong>'.get_lang('ReadThoroughly').'</strong><br />';
756
    echo get_lang('MoreDetails').' <a href="../../documentation/installation_guide.html" target="_blank">'.get_lang('ReadTheInstallationGuide').'</a>.<br />'."\n";
757
758
    if ($installType == 'update') {
759
        echo get_lang('IfYouPlanToUpgradeFromOlderVersionYouMightWantToHaveAlookAtTheChangelog').'<br />';
760
    }
761
    echo '</div>';
762
763
    $properlyAccessUrl = checkAccessUrl();
764
    if (!$properlyAccessUrl) {
765
        echo '
766
            <div class="alert alert-danger">
767
            <i class="fa fa-exclamation-triangle" aria-hidden="true"></i>&nbsp;'.
768
            sprintf(get_lang('InstallMultiURLDetectedNotMainURL'), api_get_configuration_value('root_web')).'
769
            </div>
770
        ';
771
    }
772
773
    //  SERVER REQUIREMENTS
774
    echo '<div class="RequirementHeading"><h4>'.get_lang('ServerRequirements').'</h4>';
775
    $timezone = checkPhpSettingExists('date.timezone');
776
    if (!$timezone) {
777
        echo "<div class='alert alert-warning'>
778
            <i class=\"fa fa-exclamation-triangle\" aria-hidden=\"true\"></i>&nbsp;".
779
            get_lang('DateTimezoneSettingNotSet')."</div>";
780
    }
781
782
    echo '<div class="RequirementText">'.get_lang('ServerRequirementsInfo').'</div>';
783
    echo '<div class="RequirementContent">';
784
    echo '<table class="table">
785
            <tr>
786
                <td class="requirements-item">'.get_lang('PHPVersion').' >= '.REQUIRED_PHP_VERSION.'</td>
787
                <td class="requirements-value">';
788
    if (version_compare(phpversion(), REQUIRED_PHP_VERSION, '>=') > 1) {
789
        echo '<strong><font color="red">'.get_lang('PHPVersionError').'</font></strong>';
790
    } else {
791
        echo '<strong><font color="green">'.get_lang('PHPVersionOK').' '.phpversion().'</font></strong>';
792
    }
793
    echo '</td>
794
            </tr>
795
            <tr>
796
                <td class="requirements-item"><a href="http://php.net/manual/en/book.session.php" target="_blank">Session</a> '.get_lang('Support').'</td>
797
                <td class="requirements-value">'.checkExtension('session', get_lang('Yes'), get_lang('ExtensionSessionsNotAvailable')).'</td>
798
            </tr>
799
            <tr>
800
                <td class="requirements-item"><a href="http://php.net/manual/en/book.mysql.php" target="_blank">pdo_mysql</a> '.get_lang('Support').'</td>
801
                <td class="requirements-value">'.checkExtension('pdo_mysql', get_lang('Yes'), get_lang('ExtensionMySQLNotAvailable')).'</td>
802
            </tr>
803
            <tr>
804
                <td class="requirements-item"><a href="http://php.net/manual/en/book.zip.php" target="_blank">Zip</a> '.get_lang('Support').'</td>
805
                <td class="requirements-value">'.checkExtension('zip', get_lang('Yes'), get_lang('ExtensionNotAvailable')).'</td>
806
            </tr>
807
            <tr>
808
                <td class="requirements-item"><a href="http://php.net/manual/en/book.zlib.php" target="_blank">Zlib</a> '.get_lang('Support').'</td>
809
                <td class="requirements-value">'.checkExtension('zlib', get_lang('Yes'), get_lang('ExtensionZlibNotAvailable')).'</td>
810
            </tr>
811
            <tr>
812
                <td class="requirements-item"><a href="http://php.net/manual/en/book.pcre.php" target="_blank">Perl-compatible regular expressions</a> '.get_lang('Support').'</td>
813
                <td class="requirements-value">'.checkExtension('pcre', get_lang('Yes'), get_lang('ExtensionPCRENotAvailable')).'</td>
814
            </tr>
815
            <tr>
816
                <td class="requirements-item"><a href="http://php.net/manual/en/book.xml.php" target="_blank">XML</a> '.get_lang('Support').'</td>
817
                <td class="requirements-value">'.checkExtension('xml', get_lang('Yes'), get_lang('No')).'</td>
818
            </tr>
819
            <tr>
820
                <td class="requirements-item"><a href="http://php.net/manual/en/book.intl.php" target="_blank">Internationalization</a> '.get_lang('Support').'</td>
821
                <td class="requirements-value">'.checkExtension('intl', get_lang('Yes'), get_lang('No')).'</td>
822
            </tr>
823
               <tr>
824
                <td class="requirements-item"><a href="http://php.net/manual/en/book.json.php" target="_blank">JSON</a> '.get_lang('Support').'</td>
825
                <td class="requirements-value">'.checkExtension('json', get_lang('Yes'), get_lang('No')).'</td>
826
            </tr>
827
             <tr>
828
                <td class="requirements-item"><a href="http://php.net/manual/en/book.image.php" target="_blank">GD</a> '.get_lang('Support').'</td>
829
                <td class="requirements-value">'.checkExtension('gd', get_lang('Yes'), get_lang('ExtensionGDNotAvailable')).'</td>
830
            </tr>
831
            <tr>
832
                <td class="requirements-item"><a href="http://php.net/manual/en/book.curl.php" target="_blank">cURL</a>'.get_lang('Support').'</td>
833
                <td class="requirements-value">'.checkExtension('curl', get_lang('Yes'), get_lang('No')).'</td>
834
            </tr>
835
836
            <tr>
837
                <td class="requirements-item"><a href="http://php.net/manual/en/book.mbstring.php" target="_blank">Multibyte string</a> '.get_lang('Support').' ('.get_lang('Optional').')</td>
838
                <td class="requirements-value">'.checkExtension('mbstring', get_lang('Yes'), get_lang('ExtensionMBStringNotAvailable'), true).'</td>
839
            </tr>
840
            <tr>
841
                <td class="requirements-item"><a href="http://php.net/opcache" target="_blank">Zend OpCache</a> '.get_lang('Support').' ('.get_lang('Optional').')</td>
842
                <td class="requirements-value">'.checkExtension('Zend OPcache', get_lang('Yes'), get_lang('No'), true, 'opcache.enable').'</td>
843
            </tr>
844
            <tr>
845
                <td class="requirements-item"><a href="http://php.net/apcu" target="_blank">APCu</a> '.get_lang('Support').' ('.get_lang('Optional').')</td>
846
                <td class="requirements-value">'.checkExtension('apcu', get_lang('Yes'), get_lang('No'), true, 'apc.enabled').'</td>
847
            </tr>
848
            <tr>
849
                <td class="requirements-item"><a href="http://php.net/manual/en/book.iconv.php" target="_blank">Iconv</a> '.get_lang('Support').' ('.get_lang('Optional').')</td>
850
                <td class="requirements-value">'.checkExtension('iconv', get_lang('Yes'), get_lang('No'), true).'</td>
851
            </tr>
852
            <tr>
853
                <td class="requirements-item"><a href="http://php.net/manual/en/book.ldap.php" target="_blank">LDAP</a> '.get_lang('Support').' ('.get_lang('Optional').')</td>
854
                <td class="requirements-value">'.checkExtension('ldap', get_lang('Yes'), get_lang('ExtensionLDAPNotAvailable'), true).'</td>
855
            </tr>
856
            <tr>
857
                <td class="requirements-item"><a href="http://xapian.org/" target="_blank">Xapian</a> '.get_lang('Support').' ('.get_lang('Optional').')</td>
858
                <td class="requirements-value">'.checkExtension('xapian', get_lang('Yes'), get_lang('No'), true).'</td>
859
            </tr>
860
        </table>';
861
    echo '</div>';
862
    echo '</div>';
863
864
    // RECOMMENDED SETTINGS
865
    // Note: these are the settings for Joomla, does this also apply for Chamilo?
866
    // Note: also add upload_max_filesize here so that large uploads are possible
867
    echo '<div class="RequirementHeading"><h4>'.get_lang('RecommendedSettings').'</h4>';
868
    echo '<div class="RequirementText">'.get_lang('RecommendedSettingsInfo').'</div>';
869
    echo '<div class="RequirementContent">';
870
    echo '<table class="table">
871
            <tr>
872
                <th>'.get_lang('Setting').'</th>
873
                <th>'.get_lang('Recommended').'</th>
874
                <th>'.get_lang('Actual').'</th>
875
            </tr>
876
            <tr>
877
                <td class="requirements-item"><a href="http://php.net/manual/features.safe-mode.php">Safe Mode</a></td>
878
                <td class="requirements-recommended">'.Display::label('OFF', 'success').'</td>
879
                <td class="requirements-value">'.checkPhpSetting('safe_mode', 'OFF').'</td>
880
            </tr>
881
            <tr>
882
                <td class="requirements-item"><a href="http://php.net/manual/ref.errorfunc.php#ini.display-errors">Display Errors</a></td>
883
                <td class="requirements-recommended">'.Display::label('OFF', 'success').'</td>
884
                <td class="requirements-value">'.checkPhpSetting('display_errors', 'OFF').'</td>
885
            </tr>
886
            <tr>
887
                <td class="requirements-item"><a href="http://php.net/manual/ini.core.php#ini.file-uploads">File Uploads</a></td>
888
                <td class="requirements-recommended">'.Display::label('ON', 'success').'</td>
889
                <td class="requirements-value">'.checkPhpSetting('file_uploads', 'ON').'</td>
890
            </tr>
891
            <tr>
892
                <td class="requirements-item"><a href="http://php.net/manual/ref.info.php#ini.magic-quotes-gpc">Magic Quotes GPC</a></td>
893
                <td class="requirements-recommended">'.Display::label('OFF', 'success').'</td>
894
                <td class="requirements-value">'.checkPhpSetting('magic_quotes_gpc', 'OFF').'</td>
895
            </tr>
896
            <tr>
897
                <td class="requirements-item"><a href="http://php.net/manual/ref.info.php#ini.magic-quotes-runtime">Magic Quotes Runtime</a></td>
898
                <td class="requirements-recommended">'.Display::label('OFF', 'success').'</td>
899
                <td class="requirements-value">'.checkPhpSetting('magic_quotes_runtime', 'OFF').'</td>
900
            </tr>
901
            <tr>
902
                <td class="requirements-item"><a href="http://php.net/manual/security.globals.php">Register Globals</a></td>
903
                <td class="requirements-recommended">'.Display::label('OFF', 'success').'</td>
904
                <td class="requirements-value">'.checkPhpSetting('register_globals', 'OFF').'</td>
905
            </tr>
906
            <tr>
907
                <td class="requirements-item"><a href="http://php.net/manual/ref.session.php#ini.session.auto-start">Session auto start</a></td>
908
                <td class="requirements-recommended">'.Display::label('OFF', 'success').'</td>
909
                <td class="requirements-value">'.checkPhpSetting('session.auto_start', 'OFF').'</td>
910
            </tr>
911
            <tr>
912
                <td class="requirements-item"><a href="http://php.net/manual/ini.core.php#ini.short-open-tag">Short Open Tag</a></td>
913
                <td class="requirements-recommended">'.Display::label('OFF', 'success').'</td>
914
                <td class="requirements-value">'.checkPhpSetting('short_open_tag', 'OFF').'</td>
915
            </tr>
916
            <tr>
917
                <td class="requirements-item"><a href="http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-httponly">Cookie HTTP Only</a></td>
918
                <td class="requirements-recommended">'.Display::label('ON', 'success').'</td>
919
                <td class="requirements-value">'.checkPhpSetting('session.cookie_httponly', 'ON').'</td>
920
            </tr>
921
            <tr>
922
                <td class="requirements-item"><a href="http://php.net/manual/ini.core.php#ini.upload-max-filesize">Maximum upload file size</a></td>
923
                <td class="requirements-recommended">'.Display::label('>= '.REQUIRED_MIN_UPLOAD_MAX_FILESIZE.'M', 'success').'</td>
924
                <td class="requirements-value">'.compare_setting_values(ini_get('upload_max_filesize'), REQUIRED_MIN_UPLOAD_MAX_FILESIZE).'</td>
925
            </tr>
926
            <tr>
927
                <td class="requirements-item"><a href="http://php.net/manual/ini.core.php#ini.post-max-size">Maximum post size</a></td>
928
                <td class="requirements-recommended">'.Display::label('>= '.REQUIRED_MIN_POST_MAX_SIZE.'M', 'success').'</td>
929
                <td class="requirements-value">'.compare_setting_values(ini_get('post_max_size'), REQUIRED_MIN_POST_MAX_SIZE).'</td>
930
            </tr>
931
            <tr>
932
                <td class="requirements-item"><a href="http://www.php.net/manual/en/ini.core.php#ini.memory-limit">Memory Limit</a></td>
933
                <td class="requirements-recommended">'.Display::label('>= '.REQUIRED_MIN_MEMORY_LIMIT.'M', 'success').'</td>
934
                <td class="requirements-value">'.compare_setting_values($originalMemoryLimit, REQUIRED_MIN_MEMORY_LIMIT).'</td>
935
            </tr>
936
          </table>';
937
    echo '  </div>';
938
    echo '</div>';
939
940
    // DIRECTORY AND FILE PERMISSIONS
941
    echo '<div class="RequirementHeading"><h4>'.get_lang('DirectoryAndFilePermissions').'</h4>';
942
    echo '<div class="RequirementText">'.get_lang('DirectoryAndFilePermissionsInfo').'</div>';
943
    echo '<div class="RequirementContent">';
944
945
    $course_attempt_name = '__XxTestxX__';
946
    $course_dir = api_get_path(SYS_COURSE_PATH).$course_attempt_name;
947
    $fileToCreate = 'test.html';
948
    //Just in case
949
    @unlink($course_dir.'/'.$fileToCreate);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

949
    /** @scrutinizer ignore-unhandled */ @unlink($course_dir.'/'.$fileToCreate);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
950
    @rmdir($course_dir);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for rmdir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

950
    /** @scrutinizer ignore-unhandled */ @rmdir($course_dir);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
951
952
    $perms_dir = [0777, 0755, 0775, 0770, 0750, 0700];
953
    $perms_fil = [0666, 0644, 0664, 0660, 0640, 0600];
954
    $course_test_was_created = false;
955
    $dir_perm_verified = 0777;
956
    foreach ($perms_dir as $perm) {
957
        $r = @mkdir($course_dir, $perm);
958
        if ($r === true) {
959
            $dir_perm_verified = $perm;
960
            $course_test_was_created = true;
961
            break;
962
        }
963
    }
964
965
    $fil_perm_verified = 0666;
966
    $file_course_test_was_created = false;
967
    if (is_dir($course_dir)) {
968
        foreach ($perms_fil as $perm) {
969
            if ($file_course_test_was_created == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
970
                break;
971
            }
972
            $r = @touch($course_dir.'/'.$fileToCreate, $perm);
973
            if ($r === true) {
974
                $fil_perm_verified = $perm;
975
                if (checkCourseScriptCreation($course_dir, $course_attempt_name, $fileToCreate)) {
976
                    $file_course_test_was_created = true;
977
                }
978
            }
979
        }
980
    }
981
982
    @unlink($course_dir.'/'.$fileToCreate);
983
    @rmdir($course_dir);
984
985
    $_SESSION['permissions_for_new_directories'] = $_setting['permissions_for_new_directories'] = $dir_perm_verified;
986
    $_SESSION['permissions_for_new_files'] = $_setting['permissions_for_new_files'] = $fil_perm_verified;
987
988
    $dir_perm = Display::label('0'.decoct($dir_perm_verified), 'info');
989
    $file_perm = Display::label('0'.decoct($fil_perm_verified), 'info');
990
991
    $courseTestLabel = Display::label(get_lang('No'), 'important');
992
    if ($course_test_was_created && $file_course_test_was_created) {
993
        $courseTestLabel = Display::label(get_lang('Yes'), 'success');
994
    }
995
996
    if ($course_test_was_created && !$file_course_test_was_created) {
997
        $courseTestLabel = Display::label(get_lang('Warning'), 'warning');
998
        $courseTestLabel .= '<br />'.sprintf(
999
            get_lang('InstallWarningCouldNotInterpretPHP'),
1000
            api_get_path(WEB_COURSE_PATH).$course_attempt_name.'/'.$fileToCreate
1001
        );
1002
    }
1003
1004
    if (!$course_test_was_created && !$file_course_test_was_created) {
1005
        $courseTestLabel = Display::label(get_lang('No'), 'important');
1006
    }
1007
1008
    $oldConf = '';
1009
    if (file_exists(api_get_path(SYS_CODE_PATH).'inc/conf/configuration.php')) {
1010
        $oldConf = '<tr>
1011
            <td class="requirements-item">'.api_get_path(SYS_CODE_PATH).'inc/conf</td>
1012
            <td class="requirements-value">'.check_writable(api_get_path(SYS_CODE_PATH).'inc/conf').'</td>
1013
        </tr>';
1014
    }
1015
1016
    echo '<table class="table">
1017
            '.$oldConf.'
1018
            <tr>
1019
                <td class="requirements-item">'.api_get_path(SYS_APP_PATH).'</td>
1020
                <td class="requirements-value">'.check_writable(api_get_path(SYS_APP_PATH)).'</td>
1021
            </tr>
1022
            <tr>
1023
                <td class="requirements-item">'.api_get_path(SYS_CODE_PATH).'default_course_document/images/</td>
1024
                <td class="requirements-value">'.check_writable(api_get_path(SYS_CODE_PATH).'default_course_document/images/').'</td>
1025
            </tr>
1026
            <tr>
1027
                <td class="requirements-item">'.api_get_path(SYS_CODE_PATH).'lang/</td>
1028
                <td class="requirements-value">'.check_writable(api_get_path(SYS_CODE_PATH).'lang/', true).' <br />('.get_lang('SuggestionOnlyToEnableSubLanguageFeatureOrUpgradeProcess').')</td>
1029
            </tr>
1030
            <tr>
1031
                <td class="requirements-item">'.api_get_path(SYS_PATH).'vendor/</td>
1032
                <td class="requirements-value">'.checkReadable(api_get_path(SYS_PATH).'vendor').'</td>
1033
            </tr>
1034
            <tr>
1035
                <td class="requirements-item">'.api_get_path(SYS_PUBLIC_PATH).'</td>
1036
                <td class="requirements-value">'.check_writable(api_get_path(SYS_PUBLIC_PATH)).'</td>
1037
            </tr>
1038
            <tr>
1039
                <td class="requirements-item">'.get_lang('CourseTestWasCreated').'</td>
1040
                <td class="requirements-value">'.$courseTestLabel.' </td>
1041
            </tr>
1042
            <tr>
1043
                <td class="requirements-item">'.get_lang('PermissionsForNewDirs').'</td>
1044
                <td class="requirements-value">'.$dir_perm.' </td>
1045
            </tr>
1046
            <tr>
1047
                <td class="requirements-item">'.get_lang('PermissionsForNewFiles').'</td>
1048
                <td class="requirements-value">'.$file_perm.' </td>
1049
            </tr>
1050
        </table>';
1051
    echo '  </div>';
1052
    echo '</div>';
1053
1054
    if ($installType == 'update' && (empty($updatePath) || $badUpdatePath)) {
1055
        if ($badUpdatePath) {
1056
            ?>
1057
            <div class="alert alert-warning">
1058
                <?php echo get_lang('Error'); ?>!<br />
1059
                Chamilo <?php echo implode('|', $update_from_version_8).' '.get_lang('HasNotBeenFoundInThatDir'); ?>.
1060
            </div>
1061
        <?php
1062
        } else {
1063
            echo '<br />';
1064
        } ?>
1065
            <div class="row">
1066
                <div class="col-md-12">
1067
                    <p><?php echo get_lang('OldVersionRootPath'); ?>:
1068
                        <input type="text" name="updatePath" size="50" value="<?php echo ($badUpdatePath && !empty($updatePath)) ? htmlentities($updatePath) : ''; ?>" />
1069
                    </p>
1070
                    <p>
1071
                        <button type="submit" class="btn btn-default" name="step1" value="<?php echo get_lang('Back'); ?>" >
1072
                            <em class="fa fa-backward"> <?php echo get_lang('Back'); ?></em>
1073
                        </button>
1074
                        <input type="hidden" name="is_executable" id="is_executable" value="-" />
1075
                        <button type="submit" class="btn btn-success" name="<?php echo isset($_POST['step2_update_6']) ? 'step2_update_6' : 'step2_update_8'; ?>" value="<?php echo get_lang('Next'); ?> &gt;" >
1076
                            <em class="fa fa-forward"> </em> <?php echo get_lang('Next'); ?>
1077
                        </button>
1078
                    </p>
1079
                </div>
1080
            </div>
1081
1082
        <?php
1083
    } else {
1084
        $error = false;
1085
        // First, attempt to set writing permissions if we don't have them yet
1086
        $perm = api_get_permissions_for_new_directories();
1087
        $perm_file = api_get_permissions_for_new_files();
1088
        $notWritable = [];
1089
1090
        $checked_writable = api_get_path(SYS_APP_PATH);
1091
        if (!is_writable($checked_writable)) {
1092
            $notWritable[] = $checked_writable;
1093
            @chmod($checked_writable, $perm);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for chmod(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

1093
            /** @scrutinizer ignore-unhandled */ @chmod($checked_writable, $perm);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1094
        }
1095
1096
        $checked_writable = api_get_path(SYS_PUBLIC_PATH);
1097
        if (!is_writable($checked_writable)) {
1098
            $notWritable[] = $checked_writable;
1099
            @chmod($checked_writable, $perm);
1100
        }
1101
1102
        $checked_writable = api_get_path(SYS_CODE_PATH).'default_course_document/images/';
1103
        if (!is_writable($checked_writable)) {
1104
            $notWritable[] = $checked_writable;
1105
            @chmod($checked_writable, $perm);
1106
        }
1107
1108
        if ($course_test_was_created == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1109
            $error = true;
1110
        }
1111
1112
        $checked_writable = api_get_path(CONFIGURATION_PATH).'configuration.php';
1113
        if (file_exists($checked_writable) && !is_writable($checked_writable)) {
1114
            $notWritable[] = $checked_writable;
1115
            @chmod($checked_writable, $perm_file);
1116
        }
1117
1118
        // Second, if this fails, report an error
1119
1120
        //--> The user would have to adjust the permissions manually
1121
        if (count($notWritable) > 0) {
1122
            $error = true; ?>
1123
            <div class="text-danger">
1124
                <h3 class="text-center"><?php echo get_lang('Warning'); ?></h3>
1125
                <p>
1126
                    <?php printf(get_lang('NoWritePermissionPleaseReadInstallGuide'), '<a href="../../documentation/installation_guide.html" target="blank">', '</a>'); ?>
1127
                </p>
1128
            </div>
1129
            <?php
1130
            echo '<ul>';
1131
            foreach ($notWritable as $value) {
1132
                echo '<li class="text-danger">'.$value.'</li>';
1133
            }
1134
            echo '</ul>';
1135
        } elseif (file_exists(api_get_path(CONFIGURATION_PATH).'configuration.php')) {
1136
            // Check wether a Chamilo configuration file already exists.
1137
            echo '<div class="alert alert-warning"><h4><center>';
1138
            echo get_lang('WarningExistingLMSInstallationDetected');
1139
            echo '</center></h4></div>';
1140
        }
1141
1142
        $deprecated = [
1143
            api_get_path(SYS_CODE_PATH).'exercice/',
1144
            api_get_path(SYS_CODE_PATH).'newscorm/',
1145
            api_get_path(SYS_PLUGIN_PATH).'ticket/',
1146
            api_get_path(SYS_PLUGIN_PATH).'skype/',
1147
        ];
1148
        $deprecatedToRemove = [];
1149
        foreach ($deprecated as $deprecatedDirectory) {
1150
            if (!is_dir($deprecatedDirectory)) {
1151
                continue;
1152
            }
1153
            $deprecatedToRemove[] = $deprecatedDirectory;
1154
        }
1155
1156
        if (count($deprecatedToRemove) > 0) {
1157
            ?>
1158
            <p class="text-danger"><?php echo get_lang('WarningForDeprecatedDirectoriesForUpgrade'); ?></p>
1159
            <ul>
1160
                <?php foreach ($deprecatedToRemove as $deprecatedDirectory) {
1161
                ?>
1162
                    <li class="text-danger"><?php echo $deprecatedDirectory; ?></li>
1163
                <?php
1164
            } ?>
1165
            </ul>
1166
            <?php
1167
        }
1168
1169
        if (!$properlyAccessUrl) {
1170
            $error = true;
1171
        }
1172
1173
        // And now display the choice buttons (go back or install)?>
1174
        <p align="center" style="padding-top:15px">
1175
        <button type="submit" name="step1" class="btn btn-default" onclick="javascript: window.location='index.php'; return false;" value="<?php echo get_lang('Previous'); ?>" >
1176
            <em class="fa fa-backward"> </em> <?php echo get_lang('Previous'); ?>
1177
        </button>
1178
        <button type="submit" name="step2_install" class="btn btn-success" value="<?php echo get_lang("NewInstallation"); ?>" <?php if ($error) {
1179
            echo 'disabled="disabled"';
1180
        } ?> >
1181
            <em class="fa fa-forward"> </em> <?php echo get_lang('NewInstallation'); ?>
1182
        </button>
1183
        <input type="hidden" name="is_executable" id="is_executable" value="-" />
1184
            <button type="submit" class="btn btn-default" <?php echo !$error ?: 'disabled="disabled"'; ?> name="step2_update_8" value="Upgrade from Chamilo 1.9.x">
1185
                <em class="fa fa-forward" aria-hidden="true"></em> <?php echo get_lang('UpgradeVersion'); ?>
1186
            </button>
1187
            </p>
1188
        <?php
1189
    }
1190
}
1191
1192
/**
1193
 * Displays the license (GNU GPL) as step 2, with
1194
 * - an "I accept" button named step3 to proceed to step 3;
1195
 * - a "Back" button named step1 to go back to the first step.
1196
 */
1197
function display_license_agreement()
1198
{
1199
    echo '<div class="RequirementHeading"><h2>'.display_step_sequence().get_lang('Licence').'</h2>';
1200
    echo '<p>'.get_lang('LMSLicenseInfo').'</p>';
1201
    echo '<p><a href="../../documentation/license.html" target="_blank">'.get_lang('PrintVers').'</a></p>';
1202
    echo '</div>'; ?>
1203
    <div class="row">
1204
        <div class="col-md-12">
1205
            <pre style="overflow: auto; height: 200px; margin-top: 5px;">
1206
                <?php echo api_htmlentities(@file_get_contents(api_get_path(SYS_PATH).'documentation/license.txt')); ?>
1207
            </pre>
1208
            <div class="checkbox">
1209
                <label>
1210
                    <input type="checkbox" name="accept" id="accept_licence" value="1" />
1211
                    <?php echo get_lang('IAccept'); ?>
1212
                </label>
1213
            </div>
1214
        </div>
1215
    </div>
1216
    <div class="row">
1217
        <div class="col-md-12">
1218
            <p class="alert alert-info"><?php echo get_lang('LMSMediaLicense'); ?></p>
1219
        </div>
1220
    </div>
1221
1222
    <!-- Contact information form -->
1223
    <div class="section-parameters">
1224
        <a href="javascript://" class = "advanced_parameters" >
1225
        <span id="img_plus_and_minus">&nbsp;<i class="fa fa-eye" aria-hidden="true"></i>&nbsp;<?php echo get_lang('ContactInformation'); ?></span>
1226
        </a>
1227
    </div>
1228
1229
    <div id="id_contact_form" style="display:block">
1230
        <div class="normal-message"><?php echo get_lang('ContactInformationDescription'); ?></div>
1231
        <div id="contact_registration">
1232
            <p><?php echo get_contact_registration_form(); ?></p><br />
1233
        </div>
1234
    </div>
1235
    <div class="text-center">
1236
    <button type="submit" class="btn btn-default" name="step1" value="&lt; <?php echo get_lang('Previous'); ?>" >
1237
        <em class="fa fa-backward"> </em> <?php echo get_lang('Previous'); ?>
1238
    </button>
1239
    <input type="hidden" name="is_executable" id="is_executable" value="-" />
1240
    <button type="submit" id="license-next" class="btn btn-success" name="step3" onclick="javascript: if(!document.getElementById('accept_licence').checked) { alert('<?php echo get_lang('YouMustAcceptLicence'); ?>');return false;}" value="<?php echo get_lang('Next'); ?> &gt;" >
1241
        <em class="fa fa-forward"> </em> <?php echo get_lang('Next'); ?>
1242
    </button>
1243
    </div>
1244
    <?php
1245
}
1246
1247
/**
1248
 * Get contact registration form.
1249
 */
1250
function get_contact_registration_form()
1251
{
1252
    $html = '
1253
   <div class="form-horizontal">
1254
    <div class="panel panel-default">
1255
    <div class="panel-body">
1256
    <div id="div_sent_information"></div>
1257
    <div class="form-group">
1258
            <label class="col-sm-3"><span class="form_required">*</span>'.get_lang('Name').'</label>
1259
            <div class="col-sm-9"><input id="person_name" class="form-control" type="text" name="person_name" size="30" /></div>
1260
    </div>
1261
    <div class="form-group">
1262
            <label class="col-sm-3"><span class="form_required">*</span>'.get_lang('Email').'</label>
1263
            <div class="col-sm-9"><input id="person_email" class="form-control" type="text" name="person_email" size="30" /></div>
1264
    </div>
1265
    <div class="form-group">
1266
            <label class="col-sm-3"><span class="form_required">*</span>'.get_lang('CompanyName').'</label>
1267
            <div class="col-sm-9"><input id="company_name" class="form-control" type="text" name="company_name" size="30" /></div>
1268
    </div>
1269
    <div class="form-group">
1270
        <label class="col-sm-3"><span class="form_required">*</span>'.get_lang('CompanyActivity').'</label>
1271
        <div class="col-sm-9">
1272
            <select class="selectpicker show-tick" name="company_activity" id="company_activity" >
1273
                <option value="">--- '.get_lang('SelectOne').' ---</option>
1274
                <Option value="Advertising/Marketing/PR">Advertising/Marketing/PR</Option><Option value="Agriculture/Forestry">Agriculture/Forestry</Option>
1275
                <Option value="Architecture">Architecture</Option><Option value="Banking/Finance">Banking/Finance</Option>
1276
                <Option value="Biotech/Pharmaceuticals">Biotech/Pharmaceuticals</Option><Option value="Business Equipment">Business Equipment</Option>
1277
                <Option value="Business Services">Business Services</Option><Option value="Construction">Construction</Option>
1278
                <Option value="Consulting/Research">Consulting/Research</Option><Option value="Education">Education</Option>
1279
                <Option value="Engineering">Engineering</Option><Option value="Environmental">Environmental</Option>
1280
                <Option value="Government">Government</Option><Option value="Healthcare">Health Care</Option>
1281
                <Option value="Hospitality/Lodging/Travel">Hospitality/Lodging/Travel</Option><Option value="Insurance">Insurance</Option>
1282
                <Option value="Legal">Legal</Option><Option value="Manufacturing">Manufacturing</Option>
1283
                <Option value="Media/Entertainment">Media/Entertainment</Option><Option value="Mortgage">Mortgage</Option>
1284
                <Option value="Non-Profit">Non-Profit</Option><Option value="Real Estate">Real Estate</Option>
1285
                <Option value="Restaurant">Restaurant</Option><Option value="Retail">Retail</Option>
1286
                <Option value="Shipping/Transportation">Shipping/Transportation</Option>
1287
                <Option value="Technology">Technology</Option><Option value="Telecommunications">Telecommunications</Option>
1288
                <Option value="Other">Other</Option>
1289
            </select>
1290
        </div>
1291
    </div>
1292
1293
    <div class="form-group">
1294
        <label class="col-sm-3"><span class="form_required">*</span>'.get_lang('PersonRole').'</label>
1295
        <div class="col-sm-9">
1296
            <select class="selectpicker show-tick" name="person_role" id="person_role" >
1297
                <option value="">--- '.get_lang('SelectOne').' ---</option>
1298
                <Option value="Administration">Administration</Option><Option value="CEO/President/ Owner">CEO/President/ Owner</Option>
1299
                <Option value="CFO">CFO</Option><Option value="CIO/CTO">CIO/CTO</Option>
1300
                <Option value="Consultant">Consultant</Option><Option value="Customer Service">Customer Service</Option>
1301
                <Option value="Engineer/Programmer">Engineer/Programmer</Option><Option value="Facilities/Operations">Facilities/Operations</Option>
1302
                <Option value="Finance/ Accounting Manager">Finance/ Accounting Manager</Option><Option value="Finance/ Accounting Staff">Finance/ Accounting Staff</Option>
1303
                <Option value="General Manager">General Manager</Option><Option value="Human Resources">Human Resources</Option>
1304
                <Option value="IS/IT Management">IS/IT Management</Option><Option value="IS/ IT Staff">IS/ IT Staff</Option>
1305
                <Option value="Marketing Manager">Marketing Manager</Option><Option value="Marketing Staff">Marketing Staff</Option>
1306
                <Option value="Partner/Principal">Partner/Principal</Option><Option value="Purchasing Manager">Purchasing Manager</Option>
1307
                <Option value="Sales/ Business Dev. Manager">Sales/ Business Dev. Manager</Option><Option value="Sales/ Business Dev.">Sales/ Business Dev.</Option>
1308
                <Option value="Vice President/Senior Manager">Vice President/Senior Manager</Option><Option value="Other">Other</Option>
1309
            </select>
1310
        </div>
1311
    </div>
1312
1313
    <div class="form-group">
1314
        <label class="col-sm-3"><span class="form_required">*</span>'.get_lang('CompanyCountry').'</label>
1315
        <div class="col-sm-9">'.get_countries_list_from_array(true).'</div>
1316
    </div>
1317
    <div class="form-group">
1318
        <label class="col-sm-3">'.get_lang('CompanyCity').'</label>
1319
        <div class="col-sm-9">
1320
                <input type="text" class="form-control" id="company_city" name="company_city" size="30" />
1321
        </div>
1322
    </div>
1323
    <div class="form-group">
1324
        <label class="col-sm-3">'.get_lang('WhichLanguageWouldYouLikeToUseWhenContactingYou').'</label>
1325
        <div class="col-sm-9">
1326
            <select class="selectpicker show-tick" id="language" name="language">
1327
                <option value="bulgarian">Bulgarian</option>
1328
                <option value="indonesian">Bahasa Indonesia</option>
1329
                <option value="bosnian">Bosanski</option>
1330
                <option value="german">Deutsch</option>
1331
                <option selected="selected" value="english">English</option>
1332
                <option value="spanish">Spanish</option>
1333
                <option value="french">Français</option>
1334
                <option value="italian">Italian</option>
1335
                <option value="hungarian">Magyar</option>
1336
                <option value="dutch">Nederlands</option>
1337
                <option value="brazilian">Português do Brasil</option>
1338
                <option value="portuguese">Português europeu</option>
1339
                <option value="slovenian">Slovenčina</option>
1340
            </select>
1341
        </div>
1342
    </div>
1343
1344
    <div class="form-group">
1345
        <label class="col-sm-3">'.get_lang('HaveYouThePowerToTakeFinancialDecisions').'</label>
1346
        <div class="col-sm-9">
1347
            <div class="radio">
1348
                <label>
1349
                    <input type="radio" name="financial_decision" id="financial_decision1" value="1" checked /> '.get_lang('Yes').'
1350
                </label>
1351
            </div>
1352
            <div class="radio">
1353
                <label>
1354
                    <input type="radio" name="financial_decision" id="financial_decision2" value="0" /> '.get_lang('No').'
1355
                </label>
1356
            </div>
1357
        </div>
1358
    </div>
1359
    <div class="clear"></div>
1360
    <div class="form-group">
1361
            <div class="col-sm-3">&nbsp;</div>
1362
            <div class="col-sm-9"><button type="button" class="btn btn-default" onclick="javascript:send_contact_information();" value="'.get_lang('SendInformation').'" ><em class="fa fa-floppy-o"></em> '.get_lang('SendInformation').'</button> <span id="loader-button"></span></div>
1363
    </div>
1364
    <div class="form-group">
1365
            <div class="col-sm-3">&nbsp;</div>
1366
            <div class="col-sm-9"><span class="form_required">*</span><small>'.get_lang('FieldRequired').'</small></div>
1367
    </div></div></div>
1368
    </div>';
1369
1370
    return $html;
1371
}
1372
1373
/**
1374
 * Displays a parameter in a table row.
1375
 * Used by the display_database_settings_form function.
1376
 *
1377
 * @param   string  Type of install
1378
 * @param   string  Name of parameter
1379
 * @param   string  Field name (in the HTML form)
1380
 * @param   string  Field value
1381
 * @param   string  Extra notice (to show on the right side)
1382
 * @param   bool Whether to display in update mode
1383
 * @param   string  Additional attribute for the <tr> element
1384
 */
1385
function displayDatabaseParameter(
1386
    $installType,
1387
    $parameterName,
1388
    $formFieldName,
1389
    $parameterValue,
1390
    $extra_notice,
1391
    $displayWhenUpdate = true,
1392
    $tr_attribute = ''
0 ignored issues
show
Unused Code introduced by
The parameter $tr_attribute is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1392
    /** @scrutinizer ignore-unused */ $tr_attribute = ''

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1393
) {
1394
    //echo "<tr ".$tr_attribute.">";
1395
    echo "<label class='col-sm-4'>$parameterName</label>";
1396
1397
    if ($installType == INSTALL_TYPE_UPDATE && $displayWhenUpdate) {
1398
        echo '<input type="hidden" name="'.$formFieldName.'" id="'.$formFieldName.'" value="'.api_htmlentities($parameterValue).'" />'.$parameterValue;
1399
    } else {
1400
        $inputType = $formFieldName == 'dbPassForm' ? 'password' : 'text';
1401
1402
        //Slightly limit the length of the database prefix to avoid having to cut down the databases names later on
1403
        $maxLength = $formFieldName == 'dbPrefixForm' ? '15' : MAX_FORM_FIELD_LENGTH;
1404
        if ($installType == INSTALL_TYPE_UPDATE) {
1405
            echo '<input type="hidden" name="'.$formFieldName.'" id="'.$formFieldName.'" value="'.api_htmlentities($parameterValue).'" />';
1406
            echo api_htmlentities($parameterValue);
1407
        } else {
1408
            echo '<div class="col-sm-5"><input type="'.$inputType.'" class="form-control" size="'.DATABASE_FORM_FIELD_DISPLAY_LENGTH.'" maxlength="'.$maxLength.'" name="'.$formFieldName.'" id="'.$formFieldName.'" value="'.api_htmlentities($parameterValue).'" />'."</div>";
1409
            echo '<div class="col-sm-3">'.$extra_notice.'</div>';
1410
        }
1411
    }
1412
}
1413
1414
/**
1415
 * Displays step 3 - a form where the user can enter the installation settings
1416
 * regarding the databases - login and password, names, prefixes, single
1417
 * or multiple databases, tracking or not...
1418
 *
1419
 * @param string $installType
1420
 * @param string $dbHostForm
1421
 * @param string $dbUsernameForm
1422
 * @param string $dbPassForm
1423
 * @param string $dbNameForm
1424
 * @param int    $dbPortForm
1425
 * @param string $installationProfile
1426
 */
1427
function display_database_settings_form(
1428
    $installType,
1429
    $dbHostForm,
1430
    $dbUsernameForm,
1431
    $dbPassForm,
1432
    $dbNameForm,
1433
    $dbPortForm = 3306,
1434
    $installationProfile = ''
0 ignored issues
show
Unused Code introduced by
The parameter $installationProfile is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1434
    /** @scrutinizer ignore-unused */ $installationProfile = ''

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1435
) {
1436
    if ($installType == 'update') {
1437
        global $_configuration;
1438
        $dbHostForm = $_configuration['db_host'];
1439
        $dbUsernameForm = $_configuration['db_user'];
1440
        $dbPassForm = $_configuration['db_password'];
1441
        $dbNameForm = $_configuration['main_database'];
1442
        $dbPortForm = isset($_configuration['db_port']) ? $_configuration['db_port'] : '';
1443
1444
        echo '<div class="RequirementHeading"><h2>'.display_step_sequence().get_lang('DBSetting').'</h2></div>';
1445
        echo '<div class="RequirementContent">';
1446
        echo get_lang('DBSettingUpgradeIntro');
1447
        echo '</div>';
1448
    } else {
1449
        echo '<div class="RequirementHeading"><h2>'.display_step_sequence().get_lang('DBSetting').'</h2></div>';
1450
        echo '<div class="RequirementContent">';
1451
        echo get_lang('DBSettingIntro');
1452
        echo '</div>';
1453
    } ?>
1454
    <div class="panel panel-default">
1455
        <div class="panel-body">
1456
        <div class="form-group">
1457
            <label class="col-sm-4"><?php echo get_lang('DBHost'); ?> </label>
1458
            <?php if ($installType == 'update') {
1459
        ?>
1460
            <div class="col-sm-5">
1461
                <input type="hidden" name="dbHostForm" value="<?php echo htmlentities($dbHostForm); ?>" /><?php echo $dbHostForm; ?>
1462
            </div>
1463
            <div class="col-sm-3"></div>
1464
            <?php
1465
    } else {
1466
        ?>
1467
            <div class="col-sm-5">
1468
                <input type="text" class="form-control" size="25" maxlength="50" name="dbHostForm" value="<?php echo htmlentities($dbHostForm); ?>" />
1469
            </div>
1470
            <div class="col-sm-3"><?php echo get_lang('EG').' localhost'; ?></div>
1471
            <?php
1472
    } ?>
1473
        </div>
1474
        <div class="form-group">
1475
            <label class="col-sm-4"><?php echo get_lang('DBPort'); ?> </label>
1476
            <?php if ($installType == 'update') {
1477
        ?>
1478
            <div class="col-sm-5">
1479
                <input type="hidden" name="dbPortForm" value="<?php echo htmlentities($dbPortForm); ?>" /><?php echo $dbPortForm; ?>
1480
            </div>
1481
            <div class="col-sm-3"></div>
1482
            <?php
1483
    } else {
1484
        ?>
1485
            <div class="col-sm-5">
1486
                <input type="text" class="form-control" size="25" maxlength="50" name="dbPortForm" value="<?php echo htmlentities($dbPortForm); ?>" />
1487
            </div>
1488
            <div class="col-sm-3"><?php echo get_lang('EG').' 3306'; ?></div>
1489
            <?php
1490
    } ?>
1491
        </div>
1492
        <div class="form-group">
1493
            <?php
1494
                //database user username
1495
                $example_login = get_lang('EG').' root';
1496
    displayDatabaseParameter($installType, get_lang('DBLogin'), 'dbUsernameForm', $dbUsernameForm, $example_login); ?>
1497
        </div>
1498
        <div class="form-group">
1499
            <?php
1500
            //database user password
1501
            $example_password = get_lang('EG').' '.api_generate_password();
1502
    displayDatabaseParameter($installType, get_lang('DBPassword'), 'dbPassForm', $dbPassForm, $example_password); ?>
1503
        </div>
1504
        <div class="form-group">
1505
            <?php
1506
            //Database Name fix replace weird chars
1507
            if ($installType != INSTALL_TYPE_UPDATE) {
1508
                $dbNameForm = str_replace(['-', '*', '$', ' ', '.'], '', $dbNameForm);
1509
            }
1510
1511
    displayDatabaseParameter(
1512
                $installType,
1513
                get_lang('MainDB'),
1514
                'dbNameForm',
1515
                $dbNameForm,
1516
                '&nbsp;',
1517
                null,
1518
                'id="optional_param1"'
1519
                ); ?>
1520
        </div>
1521
       <?php if ($installType != INSTALL_TYPE_UPDATE) {
1522
                    ?>
1523
        <div class="form-group">
1524
            <div class="col-sm-3"></div>
1525
            <div class="col-sm-9">
1526
            <button type="submit" class="btn btn-primary" name="step3" value="step3">
1527
                <em class="fa fa-refresh"> </em>
1528
                <?php echo get_lang('CheckDatabaseConnection'); ?>
1529
            </button>
1530
            </div>
1531
        </div>
1532
        <?php
1533
                } ?>
1534
1535
        </div>
1536
    </div>
1537
    <?php
1538
        $database_exists_text = '';
1539
    $manager = null;
1540
    try {
1541
        $manager = connectToDatabase(
1542
                $dbHostForm,
1543
                $dbUsernameForm,
1544
                $dbPassForm,
1545
                null,
1546
                $dbPortForm
1547
            );
1548
        $databases = $manager->getConnection()->getSchemaManager()->listDatabases();
1549
        if (in_array($dbNameForm, $databases)) {
1550
            $database_exists_text = '<div class="alert alert-warning">'.get_lang('ADatabaseWithTheSameNameAlreadyExists').'</div>';
1551
        }
1552
    } catch (Exception $e) {
1553
        $database_exists_text = $e->getMessage();
1554
    }
1555
1556
    if ($manager && $manager->getConnection()->isConnected()): ?>
1557
        <?php echo $database_exists_text; ?>
1558
        <div id="db_status" class="alert alert-success">
1559
            Database host: <strong><?php echo $manager->getConnection()->getHost(); ?></strong><br/>
1560
            Database port: <strong><?php echo $manager->getConnection()->getPort(); ?></strong><br/>
1561
            Database driver: <strong><?php echo $manager->getConnection()->getDriver()->getName(); ?></strong><br/>
1562
        </div>
1563
    <?php else: ?>
1564
        <div id="db_status" class="alert alert-danger">
1565
            <p><?php echo get_lang('FailedConectionDatabase'); ?></strong></p>
1566
            <code><?php echo $database_exists_text; ?></code>
1567
        </div>
1568
    <?php endif; ?>
1569
   <div class="form-group">
1570
       <div class="col-sm-6">
1571
           <button type="submit" name="step2" class="btn btn-default pull-right" value="&lt; <?php echo get_lang('Previous'); ?>" >
1572
               <em class="fa fa-backward"> </em> <?php echo get_lang('Previous'); ?>
1573
           </button>
1574
       </div>
1575
      <div class="col-sm-6">
1576
       <input type="hidden" name="is_executable" id="is_executable" value="-" />
1577
       <?php if ($manager) {
0 ignored issues
show
introduced by
$manager is of type Database, thus it always evaluated to true.
Loading history...
1578
        ?>
1579
           <button type="submit"  class="btn btn-success" name="step4" value="<?php echo get_lang('Next'); ?> &gt;" >
1580
               <em class="fa fa-forward"> </em> <?php echo get_lang('Next'); ?>
1581
           </button>
1582
       <?php
1583
    } else {
1584
        ?>
1585
           <button disabled="disabled" type="submit" class="btn btn-success disabled" name="step4" value="<?php echo get_lang('Next'); ?> &gt;" >
1586
               <em class="fa fa-forward"> </em> <?php echo get_lang('Next'); ?>
1587
           </button>
1588
       <?php
1589
    } ?>
1590
      </div>
1591
   </div>
1592
1593
    <?php
1594
}
1595
1596
function panel($content = null, $title = null, $id = null, $style = null)
1597
{
1598
    $html = '';
1599
    if (empty($style)) {
1600
        $style = 'default';
1601
    }
1602
    if (!empty($title)) {
1603
        $panelTitle = Display::div($title, ['class' => 'panel-heading']);
1604
        $panelBody = Display::div($content, ['class' => 'panel-body']);
1605
        $panelParent = Display::div($panelTitle.$panelBody, ['id' => $id, 'class' => 'panel panel-'.$style]);
1606
    } else {
1607
        $panelBody = Display::div($html, ['class' => 'panel-body']);
1608
        $panelParent = Display::div($panelBody, ['id' => $id, 'class' => 'panel panel-'.$style]);
1609
    }
1610
    $html .= $panelParent;
1611
1612
    return $html;
1613
}
1614
1615
/**
1616
 * Displays a parameter in a table row.
1617
 * Used by the display_configuration_settings_form function.
1618
 *
1619
 * @param string $installType
1620
 * @param string $parameterName
1621
 * @param string $formFieldName
1622
 * @param string $parameterValue
1623
 * @param string $displayWhenUpdate
1624
 *
1625
 * @return string
1626
 */
1627
function display_configuration_parameter(
1628
    $installType,
1629
    $parameterName,
1630
    $formFieldName,
1631
    $parameterValue,
1632
    $displayWhenUpdate = 'true'
1633
) {
1634
    $html = '<div class="form-group">';
1635
    $html .= '<label class="col-sm-6 control-label">'.$parameterName.'</label>';
1636
    if ($installType == INSTALL_TYPE_UPDATE && $displayWhenUpdate) {
1637
        $html .= '<input type="hidden" name="'.$formFieldName.'" value="'.api_htmlentities($parameterValue, ENT_QUOTES).'" />'.$parameterValue;
1638
    } else {
1639
        $html .= '<div class="col-sm-6"><input class="form-control" type="text" size="'.FORM_FIELD_DISPLAY_LENGTH.'" maxlength="'.MAX_FORM_FIELD_LENGTH.'" name="'.$formFieldName.'" value="'.api_htmlentities($parameterValue, ENT_QUOTES).'" />'."</div>";
1640
    }
1641
    $html .= "</div>";
1642
1643
    return $html;
1644
}
1645
1646
/**
1647
 * Displays step 4 of the installation - configuration settings about Chamilo itself.
1648
 *
1649
 * @param string $installType
1650
 * @param string $urlForm
1651
 * @param string $languageForm
1652
 * @param string $emailForm
1653
 * @param string $adminFirstName
1654
 * @param string $adminLastName
1655
 * @param string $adminPhoneForm
1656
 * @param string $campusForm
1657
 * @param string $institutionForm
1658
 * @param string $institutionUrlForm
1659
 * @param string $encryptPassForm
1660
 * @param bool   $allowSelfReg
1661
 * @param bool   $allowSelfRegProf
1662
 * @param string $loginForm
1663
 * @param string $passForm
1664
 */
1665
function display_configuration_settings_form(
1666
    $installType,
1667
    $urlForm,
1668
    $languageForm,
1669
    $emailForm,
1670
    $adminFirstName,
1671
    $adminLastName,
1672
    $adminPhoneForm,
1673
    $campusForm,
1674
    $institutionForm,
1675
    $institutionUrlForm,
1676
    $encryptPassForm,
1677
    $allowSelfReg,
1678
    $allowSelfRegProf,
1679
    $loginForm,
1680
    $passForm
1681
) {
1682
    if ($installType != 'update' && empty($languageForm)) {
1683
        $languageForm = $_SESSION['install_language'];
1684
    }
1685
    echo '<div class="RequirementHeading">';
1686
    echo "<h2>".display_step_sequence().get_lang("CfgSetting")."</h2>";
1687
    echo '</div>';
1688
1689
    echo '<p>'.get_lang('ConfigSettingsInfo').' <strong>app/config/configuration.php</strong></p>';
1690
1691
    // Parameter 1: administrator's login
1692
    $html = '';
1693
    $html .= display_configuration_parameter(
1694
        $installType,
1695
        get_lang('AdminLogin'),
1696
        'loginForm',
1697
        $loginForm,
1698
        $installType == 'update'
1699
    );
1700
1701
    // Parameter 2: administrator's password
1702
    if ($installType != 'update') {
1703
        $html .= display_configuration_parameter($installType, get_lang('AdminPass'), 'passForm', $passForm, false);
1704
    }
1705
1706
    // Parameters 3 and 4: administrator's names
1707
1708
    $html .= display_configuration_parameter(
1709
        $installType,
1710
        get_lang('AdminFirstName'),
1711
        'adminFirstName',
1712
        $adminFirstName
1713
    );
1714
    $html .= display_configuration_parameter($installType, get_lang('AdminLastName'), 'adminLastName', $adminLastName);
1715
1716
    //Parameter 3: administrator's email
1717
    $html .= display_configuration_parameter($installType, get_lang('AdminEmail'), 'emailForm', $emailForm);
1718
1719
    //Parameter 6: administrator's telephone
1720
    $html .= display_configuration_parameter($installType, get_lang('AdminPhone'), 'adminPhoneForm', $adminPhoneForm);
1721
    echo panel($html, get_lang('Administrator'), 'administrator');
1722
1723
    //First parameter: language
1724
    $html = '<div class="form-group">';
1725
    $html .= '<label class="col-sm-6 control-label">'.get_lang('MainLang')."</label>";
1726
    if ($installType == 'update') {
1727
        $html .= '<input type="hidden" name="languageForm" value="'.api_htmlentities($languageForm, ENT_QUOTES).'" />'.$languageForm;
1728
    } else { // new installation
1729
        $html .= '<div class="col-sm-6">';
1730
        $html .= display_language_selection_box('languageForm', $languageForm);
1731
        $html .= '</div>';
1732
    }
1733
    $html .= "</div>";
1734
1735
    //Second parameter: Chamilo URL
1736
    $html .= '<div class="form-group">';
1737
    $html .= '<label class="col-sm-6 control-label">'.get_lang('ChamiloURL').get_lang('ThisFieldIsRequired').'</label>';
1738
1739
    if ($installType == 'update') {
1740
        $html .= api_htmlentities($urlForm, ENT_QUOTES)."\n";
1741
    } else {
1742
        $html .= '<div class="col-sm-6">';
1743
        $html .= '<input class="form-control" type="text" size="40" maxlength="100" name="urlForm" value="'.api_htmlentities($urlForm, ENT_QUOTES).'" />';
1744
        $html .= '</div>';
1745
    }
1746
    $html .= '</div>';
1747
1748
    //Parameter 9: campus name
1749
    $html .= display_configuration_parameter(
1750
        $installType,
1751
        get_lang('CampusName'),
1752
        'campusForm',
1753
        $campusForm
1754
    );
1755
1756
    //Parameter 10: institute (short) name
1757
    $html .= display_configuration_parameter(
1758
        $installType,
1759
        get_lang('InstituteShortName'),
1760
        'institutionForm',
1761
        $institutionForm
1762
    );
1763
1764
    //Parameter 11: institute (short) name
1765
    $html .= display_configuration_parameter(
1766
        $installType,
1767
        get_lang('InstituteURL'),
1768
        'institutionUrlForm',
1769
        $institutionUrlForm
1770
    );
1771
1772
    $html .= '<div class="form-group">
1773
            <label class="col-sm-6 control-label">'.get_lang("EncryptMethodUserPass").'</label>
1774
        <div class="col-sm-6">';
1775
    if ($installType == 'update') {
1776
        $html .= '<input type="hidden" name="encryptPassForm" value="'.$encryptPassForm.'" />'.$encryptPassForm;
1777
    } else {
1778
        $html .= '<div class="checkbox">
1779
                    <label>
1780
                        <input  type="radio" name="encryptPassForm" value="bcrypt" id="encryptPass1" '.($encryptPassForm == 'bcrypt' ? 'checked="checked" ' : '').'/> bcrypt
1781
                    </label>';
1782
1783
        $html .= '<label>
1784
                        <input  type="radio" name="encryptPassForm" value="sha1" id="encryptPass1" '.($encryptPassForm == 'sha1' ? 'checked="checked" ' : '').'/> sha1
1785
                    </label>';
1786
1787
        $html .= '<label>
1788
                        <input type="radio" name="encryptPassForm" value="md5" id="encryptPass0" '.($encryptPassForm == 'md5' ? 'checked="checked" ' : '').'/> md5
1789
                    </label>';
1790
1791
        $html .= '<label>
1792
                        <input type="radio" name="encryptPassForm" value="none" id="encryptPass2" '.($encryptPassForm == 'none' ? 'checked="checked" ' : '').'/>'.get_lang('None').'
1793
                    </label>';
1794
        $html .= '</div>';
1795
    }
1796
    $html .= '</div></div>';
1797
1798
    $html .= '<div class="form-group">
1799
            <label class="col-sm-6 control-label">'.get_lang('AllowSelfReg').'</label>
1800
            <div class="col-sm-6">';
1801
    if ($installType == 'update') {
1802
        if ($allowSelfReg == 'true') {
1803
            $label = get_lang('Yes');
1804
        } elseif ($allowSelfReg == 'false') {
1805
            $label = get_lang('No');
1806
        } else {
1807
            $label = get_lang('AfterApproval');
1808
        }
1809
        $html .= '<input type="hidden" name="allowSelfReg" value="'.$allowSelfReg.'" />'.$label;
1810
    } else {
1811
        $html .= '<div class="control-group">';
1812
        $html .= '<label class="checkbox-inline">
1813
                        <input type="radio" name="allowSelfReg" value="true" id="allowSelfReg1" '.($allowSelfReg == 'true' ? 'checked="checked" ' : '').' /> '.get_lang('Yes').'
1814
                    </label>';
1815
        $html .= '<label class="checkbox-inline">
1816
                        <input type="radio" name="allowSelfReg" value="false" id="allowSelfReg0" '.($allowSelfReg == 'false' ? '' : 'checked="checked" ').' /> '.get_lang('No').'
1817
                    </label>';
1818
        $html .= '<label class="checkbox-inline">
1819
                    <input type="radio" name="allowSelfReg" value="approval" id="allowSelfReg2" '.($allowSelfReg == 'approval' ? '' : 'checked="checked" ').' /> '.get_lang('AfterApproval').'
1820
                </label>';
1821
        $html .= '</div>';
1822
    }
1823
    $html .= '</div>';
1824
    $html .= '</div>';
1825
1826
    $html .= '<div class="form-group">';
1827
    $html .= '<label class="col-sm-6 control-label">'.get_lang('AllowSelfRegProf').'</label>
1828
        <div class="col-sm-6">';
1829
    if ($installType == 'update') {
1830
        if ($allowSelfRegProf == 'true') {
1831
            $label = get_lang('Yes');
1832
        } else {
1833
            $label = get_lang('No');
1834
        }
1835
        $html .= '<input type="hidden" name="allowSelfRegProf" value="'.$allowSelfRegProf.'" />'.$label;
1836
    } else {
1837
        $html .= '<div class="control-group">
1838
                <label class="checkbox-inline">
1839
                    <input type="radio" name="allowSelfRegProf" value="1" id="allowSelfRegProf1" '.($allowSelfRegProf ? 'checked="checked" ' : '').'/>
1840
                '.get_lang('Yes').'
1841
                </label>';
1842
        $html .= '<label class="checkbox-inline">
1843
                    <input type="radio" name="allowSelfRegProf" value="0" id="allowSelfRegProf0" '.($allowSelfRegProf ? '' : 'checked="checked" ').' />
1844
                   '.get_lang('No').'
1845
                </label>';
1846
        $html .= '</div>';
1847
    }
1848
    $html .= '</div>
1849
    </div>';
1850
1851
    echo panel($html, get_lang('Platform'), 'platform'); ?>
1852
    <div class='form-group'>
1853
        <div class="col-sm-6">
1854
            <button type="submit" class="btn btn-default pull-right" name="step3" value="&lt; <?php echo get_lang('Previous'); ?>" ><em class="fa fa-backward"> </em> <?php echo get_lang('Previous'); ?></button>
1855
            <input type="hidden" name="is_executable" id="is_executable" value="-" />
1856
        </div>
1857
        <div class="col-sm-6">
1858
            <button class="btn btn-success" type="submit" name="step5" value="<?php echo get_lang('Next'); ?> &gt;" ><em class="fa fa-forward"> </em> <?php echo get_lang('Next'); ?></button>
1859
        </div>
1860
    </div>
1861
1862
    <?php
1863
}
1864
1865
/**
1866
 * After installation is completed (step 6), this message is displayed.
1867
 *
1868
 * @param string $installType
1869
 */
1870
function display_after_install_message($installType)
0 ignored issues
show
Unused Code introduced by
The parameter $installType is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1870
function display_after_install_message(/** @scrutinizer ignore-unused */ $installType)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1871
{
1872
    echo '<div class="RequirementContent">'.get_lang('FirstUseTip').'</div>';
1873
    echo '<div class="alert alert-warning">';
1874
    echo '<strong>'.get_lang('SecurityAdvice').'</strong>';
1875
    echo ': ';
1876
    printf(get_lang('ToProtectYourSiteMakeXReadOnlyAndDeleteY'), 'app/config/', 'main/install/');
1877
    echo '</div>'; ?></form>
1878
    <br />
1879
    <a class="btn btn-success btn-block" href="../../index.php">
1880
        <?php echo get_lang('GoToYourNewlyCreatedPortal'); ?>
1881
    </a>
1882
    <?php
1883
}
1884
1885
/**
1886
 * This function return countries list from array (hardcoded).
1887
 *
1888
 * @param bool $combo (Optional) True for returning countries list with select html
1889
 *
1890
 * @return array|string countries list
1891
 */
1892
function get_countries_list_from_array($combo = false)
1893
{
1894
    $a_countries = [
1895
        "Afghanistan", "Albania", "Algeria", "Andorra", "Angola", "Antigua and Barbuda", "Argentina", "Armenia", "Australia", "Austria", "Azerbaijan",
1896
        "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana", "Brazil", "Brunei", "Bulgaria", "Burkina Faso", "Burundi",
1897
        "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",
1898
        "Denmark", "Djibouti", "Dominica", "Dominican Republic",
1899
        "East Timor (Timor Timur)", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia",
1900
        "Fiji", "Finland", "France",
1901
        "Gabon", "Gambia, The", "Georgia", "Germany", "Ghana", "Greece", "Grenada", "Guatemala", "Guinea", "Guinea-Bissau", "Guyana",
1902
        "Haiti", "Honduras", "Hungary",
1903
        "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy",
1904
        "Jamaica", "Japan", "Jordan",
1905
        "Kazakhstan", "Kenya", "Kiribati", "Korea, North", "Korea, South", "Kuwait", "Kyrgyzstan",
1906
        "Laos", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
1907
        "Macedonia", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Mauritania", "Mauritius", "Mexico", "Micronesia", "Moldova", "Monaco", "Mongolia", "Morocco", "Mozambique", "Myanmar",
1908
        "Namibia", "Nauru", "Nepa", "Netherlands", "New Zealand", "Nicaragua", "Niger", "Nigeria", "Norway",
1909
        "Oman",
1910
        "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Poland", "Portugal",
1911
        "Qatar",
1912
        "Romania", "Russia", "Rwanda",
1913
        "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",
1914
        "Taiwan", "Tajikistan", "Tanzania", "Thailand", "Togo", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan", "Tuvalu",
1915
        "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", "United States", "Uruguay", "Uzbekistan",
1916
        "Vanuatu", "Vatican City", "Venezuela", "Vietnam",
1917
        "Yemen",
1918
        "Zambia", "Zimbabwe",
1919
    ];
1920
    if ($combo) {
1921
        $country_select = '<select class="selectpicker show-tick" id="country" name="country">';
1922
        $country_select .= '<option value="">--- '.get_lang('SelectOne').' ---</option>';
1923
        foreach ($a_countries as $country) {
1924
            $country_select .= '<option value="'.$country.'">'.$country.'</option>';
1925
        }
1926
        $country_select .= '</select>';
1927
1928
        return $country_select;
1929
    }
1930
1931
    return $a_countries;
1932
}
1933
1934
/**
1935
 * Lock settings that can't be changed in other portals.
1936
 */
1937
function lockSettings()
1938
{
1939
    $settings = api_get_locked_settings();
1940
    $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
1941
    foreach ($settings as $setting) {
1942
        $sql = "UPDATE $table SET access_url_locked = 1 WHERE variable  = '$setting'";
1943
        Database::query($sql);
1944
    }
1945
}
1946
1947
/**
1948
 * Update dir values.
1949
 */
1950
function updateDirAndFilesPermissions()
1951
{
1952
    $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
1953
    $permissions_for_new_directories = isset($_SESSION['permissions_for_new_directories']) ? $_SESSION['permissions_for_new_directories'] : 0770;
1954
    $permissions_for_new_files = isset($_SESSION['permissions_for_new_files']) ? $_SESSION['permissions_for_new_files'] : 0660;
1955
    // use decoct() to store as string
1956
    $sql = "UPDATE $table SET selected_value = '0".decoct($permissions_for_new_directories)."'
1957
              WHERE variable  = 'permissions_for_new_directories'";
1958
    Database::query($sql);
1959
1960
    $sql = "UPDATE $table SET selected_value = '0".decoct($permissions_for_new_files)."' WHERE variable  = 'permissions_for_new_files'";
1961
    Database::query($sql);
1962
1963
    if (isset($_SESSION['permissions_for_new_directories'])) {
1964
        unset($_SESSION['permissions_for_new_directories']);
1965
    }
1966
1967
    if (isset($_SESSION['permissions_for_new_files'])) {
1968
        unset($_SESSION['permissions_for_new_files']);
1969
    }
1970
}
1971
1972
/**
1973
 * @param $current_value
1974
 * @param $wanted_value
1975
 *
1976
 * @return string
1977
 */
1978
function compare_setting_values($current_value, $wanted_value)
1979
{
1980
    $current_value_string = $current_value;
1981
    $current_value = (float) $current_value;
1982
    $wanted_value = (float) $wanted_value;
1983
1984
    if ($current_value >= $wanted_value) {
1985
        return Display::label($current_value_string, 'success');
1986
    } else {
1987
        return Display::label($current_value_string, 'important');
1988
    }
1989
}
1990
1991
/**
1992
 * @param string $course_dir
1993
 * @param string $course_attempt_name
1994
 * @param string $file
1995
 *
1996
 * @return bool
1997
 */
1998
function checkCourseScriptCreation(
1999
    $course_dir,
2000
    $course_attempt_name,
2001
    $file
2002
) {
2003
    $output = false;
2004
    //Write in file
2005
    $file_name = $course_dir.'/'.$file;
2006
    $content = '123';
2007
2008
    if (is_writable($file_name)) {
2009
        if ($handler = @fopen($file_name, 'w')) {
2010
            //write content
2011
            if (fwrite($handler, $content)) {
2012
                $sock_errno = '';
2013
                $sock_errmsg = '';
2014
                $url = api_get_path(WEB_PATH).'app/courses/'.$course_attempt_name.'/'.$file;
2015
2016
                $parsed_url = parse_url($url);
2017
                //$scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'] : ''; //http
2018
                $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
2019
                // Patch if the host is the default host and is used through
2020
                // the IP address (sometimes the host is not taken correctly
2021
                // in this case)
2022
                if (empty($host) && !empty($_SERVER['HTTP_HOST'])) {
2023
                    $host = $_SERVER['HTTP_HOST'];
2024
                    $url = preg_replace('#:///#', '://'.$host.'/', $url);
2025
                }
2026
                $path = isset($parsed_url['path']) ? $parsed_url['path'] : '/';
2027
                $port = '';
2028
                $scheme = '';
2029
                switch ($parsed_url['scheme']) {
2030
                    case 'https':
2031
                        $scheme = 'ssl://';
2032
                        $port = 443;
2033
                        break;
2034
                    case 'http':
2035
                    default:
2036
                        $scheme = '';
2037
                        $port = 80;
2038
                }
2039
2040
                //Check fsockopen (not sure it works with https). If that is your case, you might want to try the
2041
                // suggestion at https://support.chamilo.org/issues/8260#note-3 (although it ignores SSL peer checks)
2042
                if ($fp = @fsockopen(str_replace('http://', $scheme, $url), $port, $sock_errno, $sock_errmsg, 60)) {
2043
                    $out = "GET $path HTTP/1.1\r\n";
2044
                    $out .= "Host: $host\r\n";
2045
                    $out .= "Connection: Close\r\n\r\n";
2046
2047
                    fwrite($fp, $out);
2048
                    while (!feof($fp)) {
2049
                        $result = str_replace("\r\n", '', fgets($fp, 128));
2050
                        if (!empty($result) && $result == '123') {
2051
                            $output = true;
2052
                        }
2053
                    }
2054
                    fclose($fp);
2055
                } elseif (ini_get('allow_url_fopen')) {
2056
                    // Check allow_url_fopen
2057
                    if ($fp = @fopen($url, 'r')) {
2058
                        while ($result = fgets($fp, 1024)) {
2059
                            if (!empty($result) && $result == '123') {
2060
                                $output = true;
2061
                            }
2062
                        }
2063
                        fclose($fp);
2064
                    }
2065
                } elseif (function_exists('curl_init')) {
2066
                    // Check if has support for cURL
2067
                    $ch = curl_init();
2068
                    curl_setopt($ch, CURLOPT_HEADER, 0);
2069
                    curl_setopt($ch, CURLOPT_URL, $url);
2070
                    //curl_setopt($ch, CURLOPT_TIMEOUT, 30);
2071
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
2072
                    $result = curl_exec($ch);
2073
                    if (!empty($result) && $result == '123') {
2074
                        $output = true;
2075
                    }
2076
                    curl_close($ch);
2077
                }
2078
            }
2079
            @fclose($handler);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fclose(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

2079
            /** @scrutinizer ignore-unhandled */ @fclose($handler);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2080
        }
2081
    }
2082
2083
    return $output;
2084
}
2085
2086
/**
2087
 * Save settings values.
2088
 *
2089
 * @param string $organizationName
2090
 * @param string $organizationUrl
2091
 * @param string $siteName
2092
 * @param string $adminEmail
2093
 * @param string $adminLastName
2094
 * @param string $adminFirstName
2095
 * @param string $language
2096
 * @param string $allowRegistration
2097
 * @param string $allowTeacherSelfRegistration
2098
 * @param string $installationProfile          The name of an installation profile file in main/install/profiles/
2099
 */
2100
function installSettings(
2101
    $organizationName,
2102
    $organizationUrl,
2103
    $siteName,
2104
    $adminEmail,
2105
    $adminLastName,
2106
    $adminFirstName,
2107
    $language,
2108
    $allowRegistration,
2109
    $allowTeacherSelfRegistration,
2110
    $installationProfile = ''
2111
) {
2112
    $allowTeacherSelfRegistration = $allowTeacherSelfRegistration ? 'true' : 'false';
2113
2114
    $settings = [
2115
        'institution' => $organizationName,
2116
        'institution_url' => $organizationUrl,
2117
        'site_name' => $siteName,
2118
        'administrator_email' => $adminEmail,
2119
        'administrator_surname' => $adminLastName,
2120
        'administrator_name' => $adminFirstName,
2121
        'platform_language' => $language,
2122
        'allow_registration' => $allowRegistration,
2123
        'allow_registration_as_teacher' => $allowTeacherSelfRegistration,
2124
    ];
2125
2126
    foreach ($settings as $variable => $value) {
2127
        $sql = "UPDATE settings_current
2128
                SET selected_value = '$value'
2129
                WHERE variable = '$variable'";
2130
        Database::query($sql);
2131
    }
2132
    installProfileSettings($installationProfile);
2133
}
2134
2135
/**
2136
 * Executes DB changes based in the classes defined in
2137
 * src/Chamilo/CoreBundle/Migrations/Schema/*.
2138
 *
2139
 * @param string        $chamiloVersion
2140
 * @param EntityManager $manager
2141
 *
2142
 * @throws \Doctrine\DBAL\DBALException
2143
 *
2144
 * @return bool
2145
 */
2146
function migrate($chamiloVersion, EntityManager $manager)
2147
{
2148
    $debug = true;
2149
    $connection = $manager->getConnection();
2150
2151
    $config = new \Doctrine\DBAL\Migrations\Configuration\Configuration($connection);
2152
2153
    // Table name that will store migrations log (will be created automatically,
2154
    // default name is: doctrine_migration_versions)
2155
    $config->setMigrationsTableName('version');
2156
    // Namespace of your migration classes, do not forget escape slashes, do not add last slash
2157
    $config->setMigrationsNamespace('Application\Migrations\Schema\V'.$chamiloVersion);
2158
    // Directory where your migrations are located
2159
    $versionPath = api_get_path(SYS_PATH).'app/Migrations/Schema/V'.$chamiloVersion;
2160
    error_log("Reading files from dir: $versionPath");
2161
    $config->setMigrationsDirectory($versionPath);
2162
    // Load your migrations
2163
    $config->registerMigrationsFromDirectory($config->getMigrationsDirectory());
2164
2165
    $migration = new \Doctrine\DBAL\Migrations\Migration($config);
2166
    $versions = $config->getMigrations();
2167
2168
    /** @var Doctrine\DBAL\Migrations\Version $migrationItem */
2169
    foreach ($versions as $version) {
2170
        $version->getMigration()->setEntityManager($manager);
2171
    }
2172
2173
    $to = null; // if $to == null then schema will be migrated to latest version
2174
2175
    echo "<pre>";
2176
    try {
2177
        // Execute migration!
2178
        $migratedSQL = $migration->migrate($to);
2179
2180
        if ($debug) {
2181
            foreach ($migratedSQL as $version => $sqlList) {
2182
                echo "VERSION: $version<br>";
2183
                echo "----------------------------------------------<br>";
2184
                $total = count($sqlList);
2185
                error_log("VERSION: $version");
2186
                error_log("# queries: ".$total);
2187
                $counter = 1;
2188
                foreach ($sqlList as $sql) {
2189
                    echo "<code>$sql</code><br>";
2190
                    error_log("$counter/$total : $sql");
2191
                    $counter++;
2192
                }
2193
            }
2194
2195
            echo "<br>DONE!<br>";
2196
        }
2197
2198
        return true;
2199
    } catch (Exception $ex) {
2200
        if ($debug) {
2201
            echo "ERROR: {$ex->getMessage()}<br>";
2202
2203
            return false;
2204
        }
2205
    }
2206
2207
    echo "</pre>";
2208
2209
    return false;
2210
}
2211
2212
/**
2213
 * @param EntityManager $em
2214
 *
2215
 * @throws \Doctrine\DBAL\DBALException
2216
 */
2217
function fixIds(EntityManager $em)
2218
{
2219
    $connection = $em->getConnection();
2220
    $database = new Database();
2221
    $database->setManager($em);
2222
    $debug = true;
2223
    if ($debug) {
2224
        error_log('fixIds');
2225
    }
2226
2227
    // Create temporary indexes to increase speed of the following operations
2228
    // Adding and removing indexes will usually take much less time than
2229
    // the execution without indexes of the queries in this function, particularly
2230
    // for large tables
2231
    $sql = "ALTER TABLE c_document ADD INDEX tmpidx_doc(c_id, id)";
2232
    $connection->executeQuery($sql);
2233
    $sql = "ALTER TABLE c_student_publication ADD INDEX tmpidx_stud (c_id, id)";
2234
    $connection->executeQuery($sql);
2235
    $sql = "ALTER TABLE c_quiz ADD INDEX tmpidx_quiz (c_id, id)";
2236
    $connection->executeQuery($sql);
2237
    $sql = "ALTER TABLE c_item_property ADD INDEX tmpidx_ip (to_group_id)";
2238
    $connection->executeQuery($sql);
2239
2240
    $sql = "SELECT * FROM c_lp_item";
2241
    $result = $connection->fetchAll($sql);
2242
    foreach ($result as $item) {
2243
        $courseId = $item['c_id'];
2244
        $iid = isset($item['iid']) ? intval($item['iid']) : 0;
2245
        $ref = isset($item['ref']) ? intval($item['ref']) : 0;
2246
        $sql = null;
2247
2248
        $newId = '';
2249
2250
        switch ($item['item_type']) {
2251
            case TOOL_LINK:
2252
                $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref";
2253
                $data = $connection->fetchAssoc($sql);
2254
                if ($data) {
2255
                    $newId = $data['iid'];
2256
                }
2257
                break;
2258
            case TOOL_STUDENTPUBLICATION:
2259
                $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref";
2260
                $data = $connection->fetchAssoc($sql);
2261
                if ($data) {
2262
                    $newId = $data['iid'];
2263
                }
2264
                break;
2265
            case TOOL_QUIZ:
2266
                $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref";
2267
                $data = $connection->fetchAssoc($sql);
2268
                if ($data) {
2269
                    $newId = $data['iid'];
2270
                }
2271
                break;
2272
            case TOOL_DOCUMENT:
2273
                $sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref";
2274
                $data = $connection->fetchAssoc($sql);
2275
                if ($data) {
2276
                    $newId = $data['iid'];
2277
                }
2278
                break;
2279
            case TOOL_FORUM:
2280
                $sql = "SELECT * FROM c_forum_forum WHERE c_id = $courseId AND forum_id = $ref";
2281
                $data = $connection->fetchAssoc($sql);
2282
                if ($data) {
2283
                    $newId = $data['iid'];
2284
                }
2285
                break;
2286
            case 'thread':
2287
                $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND thread_id = $ref";
2288
                $data = $connection->fetchAssoc($sql);
2289
                if ($data) {
2290
                    $newId = $data['iid'];
2291
                }
2292
                break;
2293
        }
2294
2295
        if (!empty($sql) && !empty($newId) && !empty($iid)) {
2296
            $sql = "UPDATE c_lp_item SET ref = $newId WHERE iid = $iid";
2297
            $connection->executeQuery($sql);
2298
        }
2299
    }
2300
2301
    // Set NULL if session = 0
2302
    $sql = "UPDATE c_item_property SET session_id = NULL WHERE session_id = 0";
2303
    $connection->executeQuery($sql);
2304
2305
    // Set NULL if group = 0
2306
    $sql = "UPDATE c_item_property SET to_group_id = NULL WHERE to_group_id = 0";
2307
    $connection->executeQuery($sql);
2308
2309
    // Set NULL if insert_user_id = 0
2310
    $sql = "UPDATE c_item_property SET insert_user_id = NULL WHERE insert_user_id = 0";
2311
    $connection->executeQuery($sql);
2312
2313
    // Delete session data of sessions that don't exist.
2314
    $sql = "DELETE FROM c_item_property
2315
            WHERE session_id IS NOT NULL AND session_id NOT IN (SELECT id FROM session)";
2316
    $connection->executeQuery($sql);
2317
2318
    // Delete group data of groups that don't exist.
2319
    $sql = "DELETE FROM c_item_property
2320
            WHERE to_group_id IS NOT NULL AND to_group_id NOT IN (SELECT DISTINCT id FROM c_group_info)";
2321
    $connection->executeQuery($sql);
2322
2323
    // This updates the group_id with c_group_info.iid instead of c_group_info.id
2324
2325
    if ($debug) {
2326
        error_log('update iids');
2327
    }
2328
2329
    $groupTableToFix = [
2330
        'c_group_rel_user',
2331
        'c_group_rel_tutor',
2332
        'c_permission_group',
2333
        'c_role_group',
2334
        'c_survey_invitation',
2335
        'c_attendance_calendar_rel_group',
2336
    ];
2337
2338
    foreach ($groupTableToFix as $table) {
2339
        $sql = "SELECT * FROM $table";
2340
        $result = $connection->fetchAll($sql);
2341
        foreach ($result as $item) {
2342
            $iid = $item['iid'];
2343
            $courseId = $item['c_id'];
2344
            $groupId = intval($item['group_id']);
2345
2346
            // Fix group id
2347
            if (!empty($groupId)) {
2348
                $sql = "SELECT * FROM c_group_info
2349
                        WHERE c_id = $courseId AND id = $groupId
2350
                        LIMIT 1";
2351
                $data = $connection->fetchAssoc($sql);
2352
                if (!empty($data)) {
2353
                    $newGroupId = $data['iid'];
2354
                    $sql = "UPDATE $table SET group_id = $newGroupId
2355
                            WHERE iid = $iid";
2356
                    $connection->executeQuery($sql);
2357
                } else {
2358
                    // The group does not exists clean this record
2359
                    $sql = "DELETE FROM $table WHERE iid = $iid";
2360
                    $connection->executeQuery($sql);
2361
                }
2362
            }
2363
        }
2364
    }
2365
2366
    // Fix c_item_property
2367
    if ($debug) {
2368
        error_log('update c_item_property');
2369
    }
2370
2371
    $sql = "SELECT * FROM course";
2372
    $courseList = $connection->fetchAll($sql);
2373
    if ($debug) {
2374
        error_log('Getting course list');
2375
    }
2376
2377
    $totalCourse = count($courseList);
2378
    $counter = 0;
2379
2380
    foreach ($courseList as $courseData) {
2381
        $courseId = $courseData['id'];
2382
        if ($debug) {
2383
            error_log('Updating course: '.$courseData['code']);
2384
        }
2385
2386
        $sql = "SELECT * FROM c_item_property WHERE c_id = $courseId";
2387
        $result = $connection->fetchAll($sql);
2388
        foreach ($result as $item) {
2389
            $sessionId = intval($item['session_id']);
2390
            $groupId = intval($item['to_group_id']);
2391
            $iid = $item['iid'];
2392
            $ref = $item['ref'];
2393
2394
            // Fix group id
2395
            if (!empty($groupId)) {
2396
                $sql = "SELECT * FROM c_group_info
2397
                        WHERE c_id = $courseId AND id = $groupId";
2398
                $data = $connection->fetchAssoc($sql);
2399
                if (!empty($data)) {
2400
                    $newGroupId = $data['iid'];
2401
                    $sql = "UPDATE c_item_property SET to_group_id = $newGroupId
2402
                            WHERE iid = $iid";
2403
                    $connection->executeQuery($sql);
2404
                } else {
2405
                    // The group does not exists clean this record
2406
                    $sql = "DELETE FROM c_item_property WHERE iid = $iid";
2407
                    $connection->executeQuery($sql);
2408
                }
2409
            }
2410
2411
            $sql = '';
2412
            $newId = '';
2413
            switch ($item['tool']) {
2414
                case TOOL_LINK:
2415
                    $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref ";
2416
                    break;
2417
                case TOOL_STUDENTPUBLICATION:
2418
                    $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref";
2419
                    break;
2420
                case TOOL_QUIZ:
2421
                    $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref";
2422
                    break;
2423
                case TOOL_DOCUMENT:
2424
                    $sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref";
2425
                    break;
2426
                case TOOL_FORUM:
2427
                    $sql = "SELECT * FROM c_forum_forum WHERE c_id = $courseId AND id = $ref";
2428
                    break;
2429
                case 'thread':
2430
                    $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND id = $ref";
2431
                    break;
2432
            }
2433
2434
            if (!empty($sql) && !empty($newId)) {
2435
                $data = $connection->fetchAssoc($sql);
2436
                if (isset($data['iid'])) {
2437
                    $newId = $data['iid'];
2438
                }
2439
                $sql = "UPDATE c_item_property SET ref = $newId WHERE iid = $iid";
2440
                error_log($sql);
2441
                $connection->executeQuery($sql);
2442
            }
2443
        }
2444
2445
        if ($debug) {
2446
            // Print a status in the log once in a while
2447
            error_log("Course process #$counter/$totalCourse");
2448
        }
2449
        $counter++;
2450
    }
2451
2452
    if ($debug) {
2453
        error_log('update gradebook_link');
2454
    }
2455
2456
    // Fix gradebook_link
2457
    $sql = "SELECT * FROM gradebook_link";
2458
    $result = $connection->fetchAll($sql);
2459
    foreach ($result as $item) {
2460
        $courseCode = $item['course_code'];
2461
        $categoryId = (int) $item['category_id'];
2462
2463
        $sql = "SELECT * FROM course WHERE code = '$courseCode'";
2464
        $courseInfo = $connection->fetchAssoc($sql);
2465
        if (empty($courseInfo)) {
2466
            continue;
2467
        }
2468
2469
        $courseId = $courseInfo['id'];
2470
2471
        $ref = $item['ref_id'];
2472
        $iid = $item['id'];
2473
2474
        $sql = '';
2475
        switch ($item['type']) {
2476
            case LINK_LEARNPATH:
2477
                $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref ";
2478
                break;
2479
            case LINK_STUDENTPUBLICATION:
2480
                $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref";
2481
                break;
2482
            case LINK_EXERCISE:
2483
                $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref";
2484
                break;
2485
            case LINK_ATTENDANCE:
2486
                //$sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref";
2487
                break;
2488
            case LINK_FORUM_THREAD:
2489
                $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND thread_id = $ref";
2490
                break;
2491
        }
2492
2493
        if (!empty($sql)) {
2494
            $data = $connection->fetchAssoc($sql);
2495
            if (isset($data) && isset($data['iid'])) {
2496
                $newId = $data['iid'];
2497
                $sql = "UPDATE gradebook_link SET ref_id = $newId
2498
                        WHERE id = $iid AND course_code = '$courseCode' AND category_id = $categoryId ";
2499
                $connection->executeQuery($sql);
2500
            }
2501
        }
2502
    }
2503
2504
    if ($debug) {
2505
        error_log('update groups');
2506
    }
2507
2508
    $sql = "SELECT * FROM groups";
2509
    $result = $connection->executeQuery($sql);
2510
    $groups = $result->fetchAll();
2511
    $oldGroups = [];
2512
    if (!empty($groups)) {
2513
        foreach ($groups as $group) {
2514
            if (empty($group['name'])) {
2515
                continue;
2516
            }
2517
2518
            $params = [
2519
                'name' => $group['name'],
2520
                'description' => $group['description'],
2521
                'group_type' => 1,
2522
                'picture' => $group['picture_uri'],
2523
                'url' => $group['url'],
2524
                'visibility' => $group['visibility'],
2525
                'updated_at' => $group['updated_on'],
2526
                'created_at' => $group['created_on'],
2527
            ];
2528
            $connection->insert('usergroup', $params);
2529
            $id = $connection->lastInsertId('id');
2530
            $oldGroups[$group['id']] = $id;
2531
        }
2532
    }
2533
2534
    if (!empty($oldGroups)) {
2535
        error_log('Moving group files');
2536
        foreach ($oldGroups as $oldId => $newId) {
2537
            $path = get_group_picture_path_by_id(
2538
                $oldId,
2539
                'system'
2540
            );
2541
2542
            if (!empty($path)) {
2543
                $newPath = str_replace(
2544
                    "groups/$oldId/",
2545
                    "groups/$newId/",
2546
                    $path['dir']
2547
                );
2548
                $command = "mv {$path['dir']} $newPath ";
2549
                error_log("Executing $command");
2550
                system($command);
2551
            }
2552
        }
2553
2554
        $sql = "SELECT * FROM group_rel_user";
2555
        $result = $connection->executeQuery($sql);
2556
        $dataList = $result->fetchAll();
2557
2558
        if (!empty($dataList)) {
2559
            foreach ($dataList as $data) {
2560
                if (isset($oldGroups[$data['group_id']])) {
2561
                    $data['group_id'] = $oldGroups[$data['group_id']];
2562
                    $userId = $data['user_id'];
2563
2564
                    $sql = "SELECT id FROM user WHERE user_id = $userId";
2565
                    $userResult = $connection->executeQuery($sql);
2566
                    $userInfo = $userResult->fetch();
2567
                    if (empty($userInfo)) {
2568
                        continue;
2569
                    }
2570
2571
                    $sql = "INSERT INTO usergroup_rel_user (usergroup_id, user_id, relation_type)
2572
                            VALUES ('{$data['group_id']}', '{$userId}', '{$data['relation_type']}')";
2573
                    $connection->executeQuery($sql);
2574
                }
2575
            }
2576
        }
2577
2578
        $sql = "SELECT * FROM group_rel_group";
2579
        $result = $connection->executeQuery($sql);
2580
        $dataList = $result->fetchAll();
2581
2582
        if (!empty($dataList)) {
2583
            foreach ($dataList as $data) {
2584
                if (isset($oldGroups[$data['group_id']]) && isset($oldGroups[$data['subgroup_id']])) {
2585
                    $data['group_id'] = $oldGroups[$data['group_id']];
2586
                    $data['subgroup_id'] = $oldGroups[$data['subgroup_id']];
2587
                    $sql = "INSERT INTO usergroup_rel_usergroup (group_id, subgroup_id, relation_type)
2588
                            VALUES ('{$data['group_id']}', '{$data['subgroup_id']}', '{$data['relation_type']}')";
2589
                    $connection->executeQuery($sql);
2590
                }
2591
            }
2592
        }
2593
2594
        $sql = "SELECT * FROM announcement_rel_group";
2595
        $result = $connection->executeQuery($sql);
2596
        $dataList = $result->fetchAll();
2597
2598
        if (!empty($dataList)) {
2599
            foreach ($dataList as $data) {
2600
                if (isset($oldGroups[$data['group_id']])) {
2601
                    // Deleting relation
2602
                    $sql = "DELETE FROM announcement_rel_group WHERE group_id = {$data['group_id']}";
2603
                    $connection->executeQuery($sql);
2604
2605
                    // Add new relation
2606
                    $data['group_id'] = $oldGroups[$data['group_id']];
2607
                    $sql = "INSERT INTO announcement_rel_group(group_id, announcement_id)
2608
                            VALUES ('{$data['group_id']}', '{$data['announcement_id']}')";
2609
                    $connection->executeQuery($sql);
2610
                }
2611
            }
2612
        }
2613
2614
        $sql = "SELECT * FROM group_rel_tag";
2615
        $result = $connection->executeQuery($sql);
2616
        $dataList = $result->fetchAll();
2617
        if (!empty($dataList)) {
2618
            foreach ($dataList as $data) {
2619
                if (isset($oldGroups[$data['group_id']])) {
2620
                    $data['group_id'] = $oldGroups[$data['group_id']];
2621
                    $sql = "INSERT INTO usergroup_rel_tag (tag_id, usergroup_id)
2622
                            VALUES ('{$data['tag_id']}', '{$data['group_id']}')";
2623
                    $connection->executeQuery($sql);
2624
                }
2625
            }
2626
        }
2627
    }
2628
2629
    if ($debug) {
2630
        error_log('update extra fields');
2631
    }
2632
2633
    // Extra fields
2634
    $extraFieldTables = [
2635
        ExtraField::USER_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_USER_FIELD),
2636
        ExtraField::COURSE_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_COURSE_FIELD),
2637
        //ExtraField::LP_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_LP_FIELD),
2638
        ExtraField::SESSION_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_SESSION_FIELD),
2639
        //ExtraField::CALENDAR_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_FIELD),
2640
        //ExtraField::QUESTION_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_FIELD),
2641
        //ExtraField::USER_FIELD_TYPE => //Database::get_main_table(TABLE_MAIN_SPECIFIC_FIELD),
2642
    ];
2643
2644
    foreach ($extraFieldTables as $type => $table) {
2645
        $sql = "SELECT * FROM $table ";
2646
        if ($debug) {
2647
            error_log($sql);
2648
        }
2649
        $result = $connection->query($sql);
2650
        $fields = $result->fetchAll();
2651
2652
        foreach ($fields as $field) {
2653
            if ($debug) {
2654
                error_log("Loading field: ".$field['field_variable']);
2655
            }
2656
            $originalId = $field['id'];
2657
2658
            $params = [
2659
                'extra_field_type' => $type,
2660
                'variable' => $field['field_variable'],
2661
                'field_type' => $field['field_type'],
2662
                'display_text' => $field['field_display_text'],
2663
                'default_value' => $field['field_default_value'],
2664
                'field_order' => $field['field_order'],
2665
                'visible' => $field['field_visible'],
2666
                'changeable' => $field['field_changeable'],
2667
                'filter' => $field['field_filter'],
2668
            ];
2669
2670
            $connection->insert('extra_field', $params);
2671
            $newExtraFieldId = $connection->lastInsertId();
2672
2673
            $values = [];
2674
            $handlerId = null;
2675
            switch ($type) {
2676
                case ExtraField::USER_FIELD_TYPE:
2677
                    $optionTable = Database::get_main_table(
2678
                        TABLE_MAIN_USER_FIELD_OPTIONS
2679
                    );
2680
                    $valueTable = Database::get_main_table(
2681
                        TABLE_MAIN_USER_FIELD_VALUES
2682
                    );
2683
                    $handlerId = 'user_id';
2684
                    break;
2685
                case ExtraField::COURSE_FIELD_TYPE:
2686
                    $optionTable = Database::get_main_table(
2687
                        TABLE_MAIN_COURSE_FIELD_OPTIONS
2688
                    );
2689
                    $valueTable = Database::get_main_table(
2690
                        TABLE_MAIN_COURSE_FIELD_VALUES
2691
                    );
2692
                    $handlerId = 'c_id';
2693
                    break;
2694
                case ExtraField::SESSION_FIELD_TYPE:
2695
                    $optionTable = Database::get_main_table(
2696
                        TABLE_MAIN_SESSION_FIELD_OPTIONS
2697
                    );
2698
                    $valueTable = Database::get_main_table(
2699
                        TABLE_MAIN_SESSION_FIELD_VALUES
2700
                    );
2701
                    $handlerId = 'session_id';
2702
                    break;
2703
            }
2704
2705
            if (!empty($optionTable)) {
2706
                $sql = "SELECT * FROM $optionTable WHERE field_id = $originalId ";
2707
                $result = $connection->query($sql);
2708
                $options = $result->fetchAll();
2709
2710
                foreach ($options as $option) {
2711
                    $params = [
2712
                        'display_text' => $option['option_display_text'],
2713
                        'field_id' => $newExtraFieldId,
2714
                        'option_order' => $option['option_order'],
2715
                        'option_value' => $option['option_value'],
2716
                    ];
2717
                    $connection->insert('extra_field_options', $params);
2718
                }
2719
2720
                $sql = "SELECT * FROM $valueTable WHERE field_id = $originalId ";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $valueTable does not seem to be defined for all execution paths leading up to this point.
Loading history...
2721
                $result = $connection->query($sql);
2722
                $values = $result->fetchAll();
2723
                if ($debug) {
2724
                    error_log("Fetch all values for field");
2725
                }
2726
            }
2727
2728
            if (!empty($values)) {
2729
                if ($debug) {
2730
                    error_log("Saving field value in new table");
2731
                }
2732
                $k = 0;
2733
                foreach ($values as $value) {
2734
                    if (isset($value[$handlerId])) {
2735
                        // Insert without the use of the entity as it reduces
2736
                        // speed to 2 records per second (much too slow)
2737
                        $params = [
2738
                            'field_id' => $newExtraFieldId,
2739
                            'value' => $value['field_value'],
2740
                            'item_id' => $value[$handlerId],
2741
                        ];
2742
                        $connection->insert('extra_field_values', $params);
2743
                        if ($debug && ($k % 10000 == 0)) {
2744
                            error_log("Saving field $k");
2745
                        }
2746
                        $k++;
2747
                    }
2748
                }
2749
            }
2750
        }
2751
    }
2752
2753
    if ($debug) {
0 ignored issues
show
introduced by
$debug is of type mixed, thus it always evaluated to true.
Loading history...
2754
        error_log('Remove index');
2755
    }
2756
2757
    // Drop temporary indexes added to increase speed of this function's queries
2758
    $sql = "ALTER TABLE c_document DROP INDEX tmpidx_doc";
2759
    $connection->executeQuery($sql);
2760
    $sql = "ALTER TABLE c_student_publication DROP INDEX tmpidx_stud";
2761
    $connection->executeQuery($sql);
2762
    $sql = "ALTER TABLE c_quiz DROP INDEX tmpidx_quiz";
2763
    $connection->executeQuery($sql);
2764
    $sql = "ALTER TABLE c_item_property DROP INDEX tmpidx_ip";
2765
    $connection->executeQuery($sql);
2766
2767
    if ($debug) {
2768
        error_log('Finish fixId function');
2769
    }
2770
2771
    fixLpId($connection, true);
2772
}
2773
2774
/**
2775
 * @param \Doctrine\DBAL\Connection $connection
2776
 * @param $debug
2777
 *
2778
 * @throws \Doctrine\DBAL\DBALException
2779
 */
2780
function fixLpId($connection, $debug)
2781
{
2782
    if ($debug) {
2783
        error_log('Fix lp.id lp.iids');
2784
    }
2785
2786
    $sql = 'SELECT id, title, code FROM course';
2787
    $result = $connection->query($sql);
2788
    $courses = $result->fetchAll();
2789
2790
    $sql = 'SELECT id FROM session';
2791
    $result = $connection->query($sql);
2792
    $sessions = $result->fetchAll();
2793
2794
    $tblCLp = Database::get_course_table(TABLE_LP_MAIN);
2795
    $tblCLpItem = Database::get_course_table(TABLE_LP_ITEM);
2796
    $toolTable = Database::get_course_table(TABLE_TOOL_LIST);
2797
2798
    if (!empty($sessions)) {
2799
        $sessions = array_column($sessions, 'id');
2800
        $sessions[] = 0;
2801
    } else {
2802
        $sessions = [0];
2803
    }
2804
2805
    foreach ($courses as $course) {
2806
        $courseId = $course['id'];
2807
        $sql = "SELECT * FROM $tblCLp WHERE c_id = $courseId AND iid <> id ORDER by iid";
2808
        $result = $connection->query($sql);
2809
        if ($debug) {
2810
            error_log('-------------');
2811
            error_log("Entering Lps in course #$courseId");
2812
            error_log($sql);
2813
        }
2814
        $lpList = $result->fetchAll();
2815
        $myOnlyLpList = [];
2816
        if (!empty($lpList)) {
2817
            foreach ($lpList as $lpInfo) {
2818
                $oldId = $lpInfo['id'];
2819
                $sql = "SELECT * FROM $tblCLpItem WHERE c_id = $courseId AND lp_id = $oldId ORDER by iid";
2820
                $result = $connection->query($sql);
2821
                $items = $result->fetchAll();
2822
                $lpInfo['lp_list'] = $items;
2823
                $myOnlyLpList[] = $lpInfo;
2824
            }
2825
        }
2826
2827
        if (!empty($myOnlyLpList)) {
2828
            foreach ($myOnlyLpList as $lpInfo) {
2829
                $lpIid = $lpInfo['iid'];
2830
                $oldId = $lpInfo['id'];
2831
                $items = $lpInfo['lp_list'];
2832
2833
                if (empty($items)) {
2834
                    continue;
2835
                }
2836
                $itemList = [];
2837
                foreach ($items as $subItem) {
2838
                    $itemList[$subItem['id']] = $subItem['iid'];
2839
                }
2840
                $variablesToFix = [
2841
                    'parent_item_id',
2842
                    'next_item_id',
2843
                    'prerequisite',
2844
                    'previous_item_id',
2845
                ];
2846
2847
                foreach ($sessions as $sessionId) {
2848
                    $correctLink = "lp/lp_controller.php?action=view&lp_id=$lpIid&id_session=$sessionId";
2849
                    $link = "newscorm/lp_controller.php?action=view&lp_id=$oldId&id_session=$sessionId";
2850
                    $secondLink = "lp/lp_controller.php?action=view&lp_id=$oldId&id_session=$sessionId";
2851
                    $sql = "UPDATE $toolTable 
2852
                        SET link = '$correctLink'
2853
                        WHERE c_id = $courseId AND (link = '$link' OR link ='$secondLink')";
2854
                    $connection->query($sql);
2855
                    if ($debug) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
2856
                        //error_log("Fix wrong c_tool links");
2857
                        //error_log($sql);
2858
                    }
2859
                }
2860
2861
                foreach ($items as $item) {
2862
                    $itemIid = $item['iid'];
2863
                    $itemId = $item['id'];
2864
                    foreach ($variablesToFix as $variable) {
2865
                        if (!empty($item[$variable]) && isset($itemList[$item[$variable]])) {
2866
                            $newId = $itemList[$item[$variable]];
2867
                            $sql = "UPDATE $tblCLpItem SET $variable = $newId 
2868
                                    WHERE iid = $itemIid AND c_id = $courseId AND lp_id = $oldId";
2869
                            $connection->query($sql);
2870
                            if ($debug) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
2871
                                //error_log($sql);
2872
                            }
2873
                        }
2874
                    }
2875
2876
                    if ($item['item_type'] == 'document' && !empty($item['path'])) {
2877
                        $oldDocumentId = $item['path'];
2878
                        $sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $oldDocumentId";
2879
                        $result = $connection->query($sql);
2880
                        $document = $result->fetch();
2881
                        if (!empty($document)) {
2882
                            $newDocumentId = $document['iid'];
2883
                            if (!empty($newDocumentId)) {
2884
                                $sql = "UPDATE $tblCLpItem SET path = $newDocumentId 
2885
                                    WHERE iid = $itemIid AND c_id = $courseId";
2886
                                $connection->query($sql);
2887
                                if ($debug) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
2888
                                    //error_log("Fix document: ");
2889
                                    //error_log($sql);
2890
                                }
2891
                            }
2892
                        }
2893
                    }
2894
2895
                    // c_lp_view
2896
                    $sql = "UPDATE c_lp_view SET last_item = $itemIid 
2897
                            WHERE c_id = $courseId AND last_item = $itemId AND lp_id = $oldId";
2898
                    $connection->query($sql);
2899
2900
                    // c_lp_item_view
2901
                    $sql = "UPDATE c_lp_item_view SET lp_item_id = $itemIid 
2902
                            WHERE c_id = $courseId AND lp_item_id = $itemId";
2903
                    $connection->query($sql);
2904
2905
                    // Update track_exercises
2906
                    $sql = "UPDATE track_e_exercises SET orig_lp_item_id = $itemIid 
2907
                            WHERE c_id = $courseId AND orig_lp_id = $oldId AND orig_lp_item_id = $itemId";
2908
                    $connection->query($sql);
2909
2910
                    // c_forum_thread
2911
                    $sql = "UPDATE c_forum_thread SET lp_item_id = $itemIid 
2912
                            WHERE c_id = $courseId AND lp_item_id = $itemId";
2913
                    $connection->query($sql);
2914
2915
                    // orig_lp_item_view_id
2916
                    $sql = "SELECT * FROM c_lp_view
2917
                            WHERE c_id = $courseId AND lp_id = $oldId";
2918
                    $result = $connection->query($sql);
2919
                    $itemViewList = $result->fetchAll();
2920
                    if ($itemViewList) {
2921
                        foreach ($itemViewList as $itemView) {
2922
                            $userId = $itemView['user_id'];
2923
                            $oldItemViewId = $itemView['id'];
2924
                            $newItemView = $itemView['iid'];
2925
2926
                            if (empty($oldItemViewId)) {
2927
                                continue;
2928
                            }
2929
2930
                            $sql = "UPDATE track_e_exercises 
2931
                                SET orig_lp_item_view_id = $newItemView 
2932
                                WHERE 
2933
                                  c_id = $courseId AND 
2934
                                  orig_lp_id = $oldId AND 
2935
                                  orig_lp_item_id = $itemIid AND 
2936
                                  orig_lp_item_view_id = $oldItemViewId AND 
2937
                                  exe_user_id = $userId                                       
2938
                                  ";
2939
                            $connection->query($sql);
2940
2941
                            /*$sql = "UPDATE c_lp_item_view
2942
                                    SET lp_view_id = $newItemView
2943
                                    WHERE
2944
                                      lp_view_id = $oldItemViewId AND
2945
                                      c_id = $courseId
2946
                                  ";
2947
                            $connection->query($sql);*/
2948
                        }
2949
                    }
2950
2951
                    $sql = "UPDATE $tblCLpItem SET lp_id = $lpIid 
2952
                            WHERE c_id = $courseId AND lp_id = $oldId AND id = $itemId";
2953
                    $connection->query($sql);
2954
2955
                    $sql = "UPDATE $tblCLpItem SET id = iid 
2956
                            WHERE c_id = $courseId AND lp_id = $oldId AND id = $itemId";
2957
                    $connection->query($sql);
2958
                }
2959
2960
                $sql = "UPDATE c_lp_view SET lp_id = $lpIid WHERE c_id = $courseId AND lp_id = $oldId";
2961
                $connection->query($sql);
2962
2963
                $sql = "UPDATE c_forum_forum SET lp_id = $lpIid WHERE c_id = $courseId AND lp_id = $oldId";
2964
                $connection->query($sql);
2965
2966
                // Update track_exercises.
2967
                $sql = "UPDATE track_e_exercises SET orig_lp_id = $lpIid 
2968
                        WHERE c_id = $courseId AND orig_lp_id = $oldId";
2969
                $connection->query($sql);
2970
2971
                $sql = "UPDATE $tblCLp SET id = iid WHERE c_id = $courseId AND id = $oldId ";
2972
                $connection->query($sql);
2973
            }
2974
        }
2975
    }
2976
2977
    if ($debug) {
2978
        error_log('END Fix lp.id lp.iids');
2979
    }
2980
}
2981
2982
/**
2983
 * @param string $distFile
2984
 * @param string $envFile
2985
 * @param array  $params
2986
 */
2987
function updateEnvFile($distFile, $envFile, $params)
2988
{
2989
    $contents = file_get_contents($distFile);
2990
    $contents = str_replace(array_keys($params), array_values($params), $contents);
2991
    file_put_contents($envFile, $contents);
2992
}
2993
2994
/**
2995
 * @param SymfonyContainer $container
2996
 * @param EntityManager $manager
2997
 */
2998
function installGroups($container, $manager)
2999
{
3000
    // Creating fos_group (groups and roles)
3001
    $groupManager = $container->get('fos_user.group_manager');
3002
    $groups = [
3003
        [
3004
            'code' => 'ADMIN',
3005
            'title' => 'Administrators',
3006
            'roles' => ['ROLE_ADMIN'],
3007
        ],
3008
        [
3009
            'code' => 'STUDENT',
3010
            'title' => 'Students',
3011
            'roles' => ['ROLE_STUDENT'],
3012
        ],
3013
        [
3014
            'code' => 'TEACHER',
3015
            'title' => 'Teachers',
3016
            'roles' => ['ROLE_TEACHER'],
3017
        ],
3018
        [
3019
            'code' => 'RRHH',
3020
            'title' => 'Human resources manager',
3021
            'roles' => ['ROLE_RRHH'],
3022
        ],
3023
        [
3024
            'code' => 'SESSION_MANAGER',
3025
            'title' => 'Session',
3026
            'roles' => ['ROLE_SESSION_MANAGER'],
3027
        ],
3028
        [
3029
            'code' => 'QUESTION_MANAGER',
3030
            'title' => 'Question manager',
3031
            'roles' => ['ROLE_QUESTION_MANAGER'],
3032
        ],
3033
        [
3034
            'code' => 'STUDENT_BOSS',
3035
            'title' => 'Student boss',
3036
            'roles' => ['ROLE_STUDENT_BOSS'],
3037
        ],
3038
        [
3039
            'code' => 'INVITEE',
3040
            'title' => 'Invitee',
3041
            'roles' => ['ROLE_INVITEE'],
3042
        ],
3043
    ];
3044
3045
    foreach ($groups as $groupData) {
3046
        $criteria = ['code' => $groupData['code']];
3047
        $groupExists = $groupManager->findGroupBy($criteria);
3048
        if (!$groupExists) {
3049
            $group = $groupManager->createGroup($groupData['title']);
3050
            $group->setCode($groupData['code']);
3051
            foreach ($groupData['roles'] as $role) {
3052
                $group->addRole($role);
3053
            }
3054
            $manager->persist($group);
3055
            $groupManager->updateGroup($group, true);
3056
        }
3057
    }
3058
}
3059
3060
/**
3061
 * @param SymfonyContainer $container
3062
 *
3063
 */
3064
function installPages($container)
3065
{
3066
    $siteManager = Container::getSiteManager();
3067
3068
    // Create site
3069
    /** @var Chamilo\PageBundle\Entity\Site $site */
3070
    $site = $siteManager->create();
3071
    $site->setHost('localhost');
3072
    $site->setEnabled(true);
3073
    $site->setName('localhost');
3074
    $site->setEnabledFrom(new \DateTime('now'));
3075
    $site->setEnabledTo(new \DateTime('+20 years'));
3076
    $site->setRelativePath('');
3077
    $site->setIsDefault(true);
3078
    $site->setLocale('en');
3079
    $siteManager->save($site);
3080
3081
    // Create home page
3082
    /** @var PageManager $pageManager */
3083
    $pageManager = $container->get('sonata.page.manager.page');
3084
    /** @var \Sonata\PageBundle\Model\Page $page */
3085
    $page = $pageManager->create();
3086
    $page->setSlug('homepage');
3087
    $page->setUrl('/');
3088
    $page->setName('homepage');
3089
    $page->setTitle('home');
3090
    $page->setEnabled(true);
3091
    $page->setDecorate(1);
3092
    $page->setRequestMethod('GET|POST|HEAD|DELETE|PUT');
3093
    $page->setTemplateCode('default');
3094
    $page->setRouteName('homepage');
3095
    //$page->setParent($this->getReference('page-homepage'));
3096
    $page->setSite($site);
3097
    $pageManager->save($page);
3098
3099
    // Create welcome page
3100
    $pageWelcome = $pageManager->create();
3101
    $pageWelcome->setSlug('welcome');
3102
    $pageWelcome->setUrl('/welcome');
3103
    $pageWelcome->setName('welcome');
3104
    $pageWelcome->setTitle('welcome');
3105
    $pageWelcome->setEnabled(true);
3106
    $pageWelcome->setDecorate(1);
3107
    $pageWelcome->setRequestMethod('GET');
3108
    $pageWelcome->setTemplateCode('default');
3109
    $pageWelcome->setRouteName('welcome');
3110
    $pageWelcome->setParent($page);
3111
    $pageWelcome->setSite($site);
3112
    $pageManager->save($pageWelcome);
3113
3114
    // Creating page blocks
3115
    $templateManager = $container->get('sonata.page.template_manager');
3116
    $template = $templateManager->get('default');
3117
    $templateContainers = $template->getContainers();
3118
3119
    $containers = [];
3120
    foreach ($templateContainers as $id => $area) {
3121
        $containers[$id] = [
3122
            'area' => $area,
3123
            'block' => false,
3124
        ];
3125
    }
3126
3127
    // Create blocks for this page
3128
    $blockInteractor = $container->get('sonata.page.block_interactor');
3129
    $parentBlock = null;
3130
    foreach ($containers as $id => $area) {
3131
        if (false === $area['block'] && $templateContainers[$id]['shared'] === false) {
3132
            $block = $blockInteractor->createNewContainer(
3133
                [
3134
                    'page' => $pageWelcome,
3135
                    'name' => $templateContainers[$id]['name'],
3136
                    'code' => $id,
3137
                ]
3138
            );
3139
3140
            if ($id === 'content' && $templateContainers[$id]['name'] == 'Main content') {
3141
                $parentBlock = $block;
3142
            }
3143
        }
3144
    }
3145
3146
    // Create block in main content
3147
    $block = $container->get('sonata.page.manager.block');
3148
    /** @var \Sonata\BlockBundle\Model\Block $myBlock */
3149
    $myBlock = $block->create();
3150
    $myBlock->setType('sonata.formatter.block.formatter');
3151
    $myBlock->setSetting('format', 'richhtml');
3152
    $myBlock->setSetting('content', '');
3153
    $myBlock->setSetting('rawContent', '');
3154
    $myBlock->setSetting('template', '@SonataFormatter/Block/block_formatter.html.twig');
3155
    $myBlock->setParent($parentBlock);
3156
    $pageWelcome->addBlocks($myBlock);
3157
    $pageManager->save($pageWelcome);
3158
}
3159
3160
/**
3161
 * @param SymfonyContainer $container
3162
 * @param EntityManager $manager
3163
 */
3164
function installSchemas($container, $manager)
3165
{
3166
    $settingsManager = Container::getSettingsManager();
3167
3168
    $accessUrl = $manager->getRepository('ChamiloCoreBundle:AccessUrl')->find(1);
3169
    if (!$accessUrl) {
3170
        // Creating AccessUrl
3171
        $accessUrl = new AccessUrl();
3172
        $accessUrl
3173
            ->setUrl('http://localhost/')
3174
            ->setDescription('')
3175
            ->setActive(1)
3176
        ;
3177
        $manager->persist($accessUrl);
3178
        $manager->flush();
3179
    }
3180
3181
    // Install course tools (table "tool")
3182
    $toolChain = $container->get('chamilo_course.tool_chain');
3183
    $toolChain->createTools($manager);
3184
3185
    // Installing schemas (filling settings_current table)
3186
    $settingsManager->installSchemas($accessUrl);
3187
}
3188
3189
/**
3190
 * @param SymfonyContainer $container
3191
 */
3192
function updateWithContainer($container)
3193
{
3194
    Container::setContainer($container);
3195
    Container::setLegacyServices($container);
3196
3197
    $manager = Database::getManager();
3198
3199
    installGroups($container, $manager);
3200
    installSchemas($container, $manager);
3201
    installPages($container);
3202
}
3203
3204
/**
3205
 * After the schema was created (table creation), the function adds
3206
 * admin/platform information.
3207
 *
3208
 * @param \Psr\Container\ContainerInterface $container
3209
 * @param string                            $sysPath
3210
 * @param string                            $encryptPassForm
3211
 * @param string                            $passForm
3212
 * @param string                            $adminLastName
3213
 * @param string                            $adminFirstName
3214
 * @param string                            $loginForm
3215
 * @param string                            $emailForm
3216
 * @param string                            $adminPhoneForm
3217
 * @param string                            $languageForm
3218
 * @param string                            $institutionForm
3219
 * @param string                            $institutionUrlForm
3220
 * @param string                            $siteName
3221
 * @param string                            $allowSelfReg
3222
 * @param string                            $allowSelfRegProf
3223
 * @param string                            $installationProfile Installation profile, if any was provided
3224
 */
3225
function finishInstallationWithContainer(
3226
    $container,
3227
    $sysPath,
3228
    $encryptPassForm,
3229
    $passForm,
3230
    $adminLastName,
3231
    $adminFirstName,
3232
    $loginForm,
3233
    $emailForm,
3234
    $adminPhoneForm,
3235
    $languageForm,
3236
    $institutionForm,
3237
    $institutionUrlForm,
3238
    $siteName,
3239
    $allowSelfReg,
3240
    $allowSelfRegProf,
3241
    $installationProfile = ''
3242
) {
3243
    $sysPath = !empty($sysPath) ? $sysPath : api_get_path(SYS_PATH);
3244
    Container::setContainer($container);
3245
    Container::setLegacyServices($container);
3246
3247
    $manager = Database::getManager();
3248
    $connection = $manager->getConnection();
3249
3250
    $sql = getVersionTable();
3251
3252
    // Add version table
3253
    $connection->executeQuery($sql);
3254
3255
    // Add tickets defaults
3256
    $ticketProject = new TicketProject();
3257
    $ticketProject
3258
        ->setId(1)
3259
        ->setName('Ticket System')
3260
        ->setInsertUserId(1);
3261
3262
    $manager->persist($ticketProject);
3263
    $manager->flush();
3264
3265
    $categories = [
3266
        get_lang('TicketEnrollment') => get_lang('TicketsAboutEnrollment'),
3267
        get_lang('TicketGeneralInformation') => get_lang('TicketsAboutGeneralInformation'),
3268
        get_lang('TicketRequestAndPapework') => get_lang('TicketsAboutRequestAndPapework'),
3269
        get_lang('TicketAcademicIncidence') => get_lang('TicketsAboutAcademicIncidence'),
3270
        get_lang('TicketVirtualCampus') => get_lang('TicketsAboutVirtualCampus'),
3271
        get_lang('TicketOnlineEvaluation') => get_lang('TicketsAboutOnlineEvaluation'),
3272
    ];
3273
3274
    $i = 1;
3275
    foreach ($categories as $category => $description) {
3276
        // Online evaluation requires a course
3277
        $ticketCategory = new TicketCategory();
3278
        $ticketCategory
3279
            ->setId($i)
3280
            ->setName($category)
3281
            ->setDescription($description)
3282
            ->setProject($ticketProject)
3283
            ->setInsertUserId(1);
3284
3285
        $isRequired = $i == 6;
3286
        $ticketCategory->setCourseRequired($isRequired);
3287
3288
        $manager->persist($ticketCategory);
3289
        $manager->flush();
3290
3291
        $i++;
3292
    }
3293
3294
    // Default Priorities
3295
    $defaultPriorities = [
3296
        TicketManager::PRIORITY_NORMAL => get_lang('PriorityNormal'),
3297
        TicketManager::PRIORITY_HIGH => get_lang('PriorityHigh'),
3298
        TicketManager::PRIORITY_LOW => get_lang('PriorityLow'),
3299
    ];
3300
3301
    $i = 1;
3302
    foreach ($defaultPriorities as $code => $priority) {
3303
        $ticketPriority = new TicketPriority();
3304
        $ticketPriority
3305
            ->setId($i)
3306
            ->setName($priority)
3307
            ->setCode($code)
3308
            ->setInsertUserId(1);
3309
3310
        $manager->persist($ticketPriority);
3311
        $manager->flush();
3312
        $i++;
3313
    }
3314
3315
    $table = Database::get_main_table(TABLE_TICKET_STATUS);
3316
3317
    // Default status
3318
    $defaultStatus = [
3319
        TicketManager::STATUS_NEW => get_lang('StatusNew'),
3320
        TicketManager::STATUS_PENDING => get_lang('StatusPending'),
3321
        TicketManager::STATUS_UNCONFIRMED => get_lang('StatusUnconfirmed'),
3322
        TicketManager::STATUS_CLOSE => get_lang('StatusClose'),
3323
        TicketManager::STATUS_FORWARDED => get_lang('StatusForwarded'),
3324
    ];
3325
3326
    $i = 1;
3327
    foreach ($defaultStatus as $code => $status) {
3328
        $attributes = [
3329
            'id' => $i,
3330
            'code' => $code,
3331
            'name' => $status,
3332
        ];
3333
        Database::insert($table, $attributes);
3334
        $i++;
3335
    }
3336
3337
    installGroups($container, $manager);
3338
    installSchemas($container, $manager);
3339
    installPages($container);
3340
3341
    // Inserting default data
3342
    $data = file_get_contents($sysPath.'main/install/data.sql');
3343
    $result = $manager->getConnection()->prepare($data);
3344
    $result->execute();
3345
    $result->closeCursor();
3346
3347
    UserManager::setPasswordEncryption($encryptPassForm);
3348
3349
    // Create admin user.
3350
    @UserManager::create_user(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for create_user(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

3350
    /** @scrutinizer ignore-unhandled */ @UserManager::create_user(

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
3351
        $adminFirstName,
3352
        $adminLastName,
3353
        1,
3354
        $emailForm,
3355
        $loginForm,
3356
        $passForm,
3357
        'ADMIN', //$official_code = '',
3358
        $languageForm,
3359
        $adminPhoneForm,
3360
        '', //$picture_uri = '',
3361
        PLATFORM_AUTH_SOURCE,
3362
        '', //$expirationDate,
3363
        1,
3364
        0,
3365
        null,
3366
        '',
3367
        false, //$send_mail = false,
3368
        true, //$isAdmin = false
3369
            '',
3370
        false,
3371
        '',
3372
        1
3373
    );
3374
3375
    // Create anonymous user.
3376
    @UserManager::create_user(
3377
        'Joe',
3378
        'Anonymous',
3379
        6,
3380
        'anonymous@localhost',
3381
        'anon',
3382
        'anon',
3383
        'anonymous', //$official_code = '',
3384
        $languageForm,
3385
        '',
3386
        '', //$picture_uri = '',
3387
        PLATFORM_AUTH_SOURCE,
3388
        '',
3389
        1,
3390
        0,
3391
        null,
3392
        '',
3393
        false, //$send_mail = false,
3394
        false, //$isAdmin = false
3395
        '',
3396
        false,
3397
        '',
3398
        1
3399
    );
3400
3401
    // Set default language
3402
    $sql = "UPDATE language SET available = 1 WHERE dokeos_folder = '$languageForm'";
3403
    Database::query($sql);
3404
3405
    // Install settings
3406
    installSettings(
3407
        $institutionForm,
3408
        $institutionUrlForm,
3409
        $siteName,
3410
        $emailForm,
3411
        $adminLastName,
3412
        $adminFirstName,
3413
        $languageForm,
3414
        $allowSelfReg,
3415
        $allowSelfRegProf,
3416
        $installationProfile
3417
    );
3418
3419
    lockSettings();
3420
    updateDirAndFilesPermissions();
3421
3422
    // Set the latest version
3423
    /*$path = $sysPath.'app/Migrations/Schema/V111/';
3424
    $finder = new \Symfony\Component\Finder\Finder();
3425
    $files = $finder->files()->in($path);
3426
3427
    // Needed for chash
3428
    createVersionTable();
3429
3430
    foreach ($files as $version) {
3431
        $version = str_replace(['Version', '.php'], '', $version->getFilename());
3432
        $sql = "INSERT INTO version (version) VALUES ('$version')";
3433
        Database::query($sql);
3434
    }*/
3435
}
3436
3437
/**
3438
 * Creates 'version' table.
3439
 */
3440
function createVersionTable()
3441
{
3442
    $sql = getVersionTable();
3443
    Database::query($sql);
3444
}
3445
3446
/**
3447
 * Get version creation table query.
3448
 *
3449
 * @return string
3450
 */
3451
function getVersionTable()
3452
{
3453
    return 'CREATE TABLE IF NOT EXISTS version (id int unsigned NOT NULL AUTO_INCREMENT, version varchar(20), PRIMARY KEY(id), UNIQUE(version));';
3454
}
3455
3456
/**
3457
 * Update settings based on installation profile defined in a JSON file.
3458
 *
3459
 * @param string $installationProfile The name of the JSON file in main/install/profiles/ folder
3460
 *
3461
 * @return bool false on failure (no bad consequences anyway, just ignoring profile)
3462
 */
3463
function installProfileSettings($installationProfile = '')
3464
{
3465
    if (empty($installationProfile)) {
3466
        return false;
3467
    }
3468
    $jsonPath = api_get_path(SYS_PATH).'main/install/profiles/'.$installationProfile.'.json';
3469
    // Make sure the path to the profile is not hacked
3470
    if (!Security::check_abs_path($jsonPath, api_get_path(SYS_PATH).'main/install/profiles/')) {
3471
        return false;
3472
    }
3473
    if (!is_file($jsonPath)) {
3474
        return false;
3475
    }
3476
    if (!is_readable($jsonPath)) {
3477
        return false;
3478
    }
3479
    if (!function_exists('json_decode')) {
3480
        // The php-json extension is not available. Ignore profile.
3481
        return false;
3482
    }
3483
    $json = file_get_contents($jsonPath);
3484
    $params = json_decode($json);
3485
    if ($params === false or $params === null) {
3486
        return false;
3487
    }
3488
    $settings = $params->params;
3489
    if (!empty($params->parent)) {
3490
        installProfileSettings($params->parent);
3491
    }
3492
    foreach ($settings as $id => $param) {
3493
        $sql = "UPDATE settings_current
3494
                SET selected_value = '".$param->selected_value."'
3495
                WHERE variable = '".$param->variable."'";
3496
        if (!empty($param->subkey)) {
3497
            $sql .= " AND subkey='".$param->subkey."'";
3498
        }
3499
        Database::query($sql);
3500
    }
3501
3502
    return true;
3503
}
3504
3505
/**
3506
 * Quick function to remove a directory with its subdirectories.
3507
 *
3508
 * @param $dir
3509
 */
3510
function rrmdir($dir)
3511
{
3512
    if (is_dir($dir)) {
3513
        $objects = scandir($dir);
3514
        foreach ($objects as $object) {
3515
            if ($object != "." && $object != "..") {
3516
                if (filetype($dir."/".$object) == "dir") {
3517
                    @rrmdir($dir."/".$object);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for rrmdir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

3517
                    /** @scrutinizer ignore-unhandled */ @rrmdir($dir."/".$object);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
Are you sure the usage of rrmdir($dir . '/' . $object) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
3518
                } else {
3519
                    @unlink($dir."/".$object);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

3519
                    /** @scrutinizer ignore-unhandled */ @unlink($dir."/".$object);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
3520
                }
3521
            }
3522
        }
3523
        reset($objects);
3524
        rmdir($dir);
3525
    }
3526
}
3527
3528
function get_group_picture_path_by_id($id, $type = 'web', $preview = false, $anonymous = false)
3529
{
3530
    switch ($type) {
3531
        case 'system': // Base: absolute system path.
3532
            $base = api_get_path(SYS_UPLOAD_PATH);
3533
            break;
3534
        case 'web': // Base: absolute web path.
3535
        default:
3536
            $base = api_get_path(WEB_UPLOAD_PATH);
3537
            break;
3538
    }
3539
3540
    $noPicturePath = ['dir' => $base.'img/', 'file' => 'unknown.jpg'];
3541
3542
    if (empty($id) || empty($type)) {
3543
        return $anonymous ? $noPicturePath : ['dir' => '', 'file' => ''];
3544
    }
3545
3546
    $id = intval($id);
3547
3548
    //$group_table = Database::get_main_table(TABLE_MAIN_GROUP);
3549
    $group_table = 'groups';
3550
    $sql = "SELECT picture_uri FROM $group_table WHERE id=".$id;
3551
    $res = Database::query($sql);
3552
3553
    if (!Database::num_rows($res)) {
3554
        return $anonymous ? $noPicturePath : ['dir' => '', 'file' => ''];
3555
    }
3556
3557
    $user = Database::fetch_array($res);
3558
    $picture_filename = trim($user['picture_uri']);
3559
3560
    if (api_get_setting('split_users_upload_directory') === 'true') {
3561
        if (!empty($picture_filename)) {
3562
            $dir = $base.'groups/'.substr($picture_filename, 0, 1).'/'.$id.'/';
3563
        } elseif ($preview) {
3564
            $dir = $base.'groups/'.substr((string) $id, 0, 1).'/'.$id.'/';
3565
        } else {
3566
            $dir = $base.'groups/'.$id.'/';
3567
        }
3568
    } else {
3569
        $dir = $base.'groups/'.$id.'/';
3570
    }
3571
3572
    if (empty($picture_filename) && $anonymous) {
3573
        return $noPicturePath;
3574
    }
3575
3576
    return ['dir' => $dir, 'file' => $picture_filename];
3577
}
3578
3579
/**
3580
 * Control the different steps of the migration through a big switch.
3581
 *
3582
 * @param string        $fromVersion
3583
 * @param EntityManager $manager
3584
 * @param bool          $processFiles
3585
 *
3586
 * @return bool Always returns true except if the process is broken
3587
 */
3588
function migrateSwitch($fromVersion, $manager, $processFiles = true)
3589
{
3590
    error_log('Starting migration process from '.$fromVersion.' ('.date('Y-m-d H:i:s').')');
3591
3592
    echo '<a class="btn btn-default" href="javascript:void(0)" id="details_button">'.get_lang('Details').'</a><br />';
3593
    echo '<div id="details" style="display:none">';
3594
3595
    $connection = $manager->getConnection();
3596
3597
    $database = new Database();
3598
    $database->setManager($manager);
3599
3600
    switch ($fromVersion) {
3601
        case '1.9.0':
3602
        case '1.9.2':
3603
        case '1.9.4':
3604
        case '1.9.6':
3605
        case '1.9.6.1':
3606
        case '1.9.8':
3607
        case '1.9.8.1':
3608
        case '1.9.8.2':
3609
        case '1.9.10':
3610
        case '1.9.10.2':
3611
        case '1.9.10.4':
3612
        case '1.9.10.6':
3613
            $database = new Database();
3614
            $database->setManager($manager);
3615
3616
            // Fix type "enum" before running the migration with Doctrine
3617
            $connection->executeQuery("ALTER TABLE course_category MODIFY COLUMN auth_course_child VARCHAR(40) DEFAULT 'TRUE'");
3618
            $connection->executeQuery("ALTER TABLE course_category MODIFY COLUMN auth_cat_child VARCHAR(40) DEFAULT 'TRUE'");
3619
            $connection->executeQuery("ALTER TABLE c_quiz_answer MODIFY COLUMN hotspot_type varchar(40) default NULL");
3620
            $connection->executeQuery("ALTER TABLE c_tool MODIFY COLUMN target varchar(20) NOT NULL default '_self'");
3621
            $connection->executeQuery("ALTER TABLE c_link MODIFY COLUMN on_homepage char(10) NOT NULL default '0'");
3622
            $connection->executeQuery("ALTER TABLE c_blog_rating MODIFY COLUMN rating_type char(40) NOT NULL default 'post'");
3623
            $connection->executeQuery("ALTER TABLE c_survey MODIFY COLUMN anonymous char(10) NOT NULL default '0'");
3624
            $connection->executeQuery("ALTER TABLE c_document MODIFY COLUMN filetype char(10) NOT NULL default 'file'");
3625
            $connection->executeQuery("ALTER TABLE c_student_publication MODIFY COLUMN filetype char(10) NOT NULL default 'file'");
3626
3627
            // Migrate using the migration files located in:
3628
            // src/Chamilo/CoreBundle/Migrations/Schema/V110
3629
            $result = migrate(
3630
                110,
3631
                $manager
3632
            );
3633
3634
            if ($result) {
3635
                error_log('Migrations files were executed ('.date('Y-m-d H:i:s').')');
3636
                fixIds($manager);
3637
                error_log('fixIds finished ('.date('Y-m-d H:i:s').')');
3638
3639
                $connection->executeQuery("UPDATE settings_current SET selected_value = '1.10.0' WHERE variable = 'chamilo_database_version'");
3640
3641
                if ($processFiles) {
3642
                    $fromVersionShort = '1.9';
3643
                    include __DIR__.'/update-files-1.9.0-1.10.0.inc.php';
3644
                    // Only updates the configuration.inc.php with the new version
3645
                    include __DIR__.'/update-configuration.inc.php';
3646
3647
                    $configurationFiles = [
3648
                        'mail.conf.php',
3649
                        'profile.conf.php',
3650
                        'course_info.conf.php',
3651
                        'add_course.conf.php',
3652
                        'events.conf.php',
3653
                        'auth.conf.php',
3654
                    ];
3655
3656
                    error_log('Copy conf files');
3657
3658
                    foreach ($configurationFiles as $file) {
3659
                        if (file_exists(api_get_path(SYS_CODE_PATH).'inc/conf/'.$file)) {
3660
                            copy(
3661
                                api_get_path(SYS_CODE_PATH).'inc/conf/'.$file,
3662
                                api_get_path(CONFIGURATION_PATH).$file
3663
                            );
3664
                        }
3665
                    }
3666
                }
3667
3668
                error_log('Upgrade 1.10.x process concluded! ('.date('Y-m-d H:i:s').')');
3669
            } else {
3670
                error_log('There was an error during running migrations. Check error.log');
3671
                break;
3672
            }
3673
            // no break
3674
        case '1.10.0':
3675
        case '1.10.2':
3676
        case '1.10.4':
3677
        case '1.10.6':
3678
        case '1.10.8':
3679
        case '1.10.8':
3680
            $database = new Database();
3681
            $database->setManager($manager);
3682
            // Migrate using the migration files located in:
3683
            // src/Chamilo/CoreBundle/Migrations/Schema/V111
3684
            $result = migrate(111, $manager);
3685
3686
            if ($result) {
3687
                error_log('Migrations files were executed ('.date('Y-m-d H:i:s').')');
3688
3689
                fixPostGroupIds($connection);
3690
3691
                $sql = "UPDATE settings_current SET selected_value = '1.11.0' WHERE variable = 'chamilo_database_version'";
3692
                $connection->executeQuery($sql);
3693
                if ($processFiles) {
3694
                    error_log('Update config files');
3695
                    $fromVersionShort = '1.10';
3696
                    include __DIR__.'/update-files-1.10.0-1.11.0.inc.php';
3697
                    // Only updates the configuration.inc.php with the new version
3698
                    include __DIR__.'/update-configuration.inc.php';
3699
                }
3700
                error_log('Upgrade 1.11.x process concluded!  ('.date('Y-m-d H:i:s').')');
3701
            } else {
3702
                error_log('There was an error during running migrations. Check error.log');
3703
            }
3704
            // no break
3705
        case '1.11.0':
3706
        case '1.11.1':
3707
        case '1.11.2':
3708
        case '1.11.4':
3709
        case '1.11.6':
3710
        case '1.11.8':
3711
        case '1.11.10':
3712
            $database = new Database();
3713
            $database->setManager($manager);
3714
            // Migrate using the migration files located in:
3715
            // src/Chamilo/CoreBundle/Migrations/Schema/V111
3716
            $result = migrate(200, $manager);
3717
3718
            if ($result) {
3719
                error_log('Migrations files were executed ('.date('Y-m-d H:i:s').')');
3720
                $sql = "UPDATE settings_current SET selected_value = '2.0.0' WHERE variable = 'chamilo_database_version'";
3721
                $connection->executeQuery($sql);
3722
                if ($processFiles) {
3723
                    error_log('Update config files');
3724
                    $fromVersionShort = '1.11';
3725
                    include __DIR__.'/update-files-1.11.0-2.0.0.inc.php';
3726
                    // Only updates the configuration.inc.php with the new version
3727
                    include __DIR__.'/update-configuration.inc.php';
3728
                }
3729
                error_log('Upgrade 2.0.0 process concluded!  ('.date('Y-m-d H:i:s').')');
3730
            } else {
3731
                error_log('There was an error during running migrations. Check error.log');
3732
            }
3733
            break;
3734
        default:
3735
            break;
3736
    }
3737
3738
    echo '</div>';
3739
3740
    return true;
3741
}
3742
3743
/**
3744
 * @param \Doctrine\DBAL\Connection $connection
3745
 */
3746
function fixPostGroupIds($connection)
3747
{
3748
    $connection->executeQuery("ALTER TABLE course_category MODIFY COLUMN auth_course_child VARCHAR(40) DEFAULT 'TRUE'");
3749
    error_log('Fix c_student_publication.post_group_id');
3750
3751
    // Fix post_group_id
3752
    $sql = "SELECT * FROM c_student_publication 
3753
            WHERE (post_group_id <> 0 AND post_group_id is not null)";
3754
    $statement = $connection->executeQuery($sql);
3755
    $result = $statement->fetchAll();
3756
3757
    foreach ($result as $row) {
3758
        $groupId = $row['post_group_id'];
3759
        $courseId = $row['c_id'];
3760
        $workIid = $row['iid'];
3761
        $sql = "SELECT iid from c_group_info 
3762
                WHERE c_id = $courseId AND id = $groupId";
3763
        $statement = $connection->executeQuery($sql);
3764
        $count = $statement->rowCount();
3765
        if ($count > 0) {
3766
            $rowGroup = $statement->fetch();
3767
            $newGroupId = $rowGroup['iid'];
3768
            if ($newGroupId == $groupId) {
3769
                continue;
3770
            }
3771
            if ($newGroupId) {
3772
                $sql = "UPDATE c_student_publication 
3773
                        SET post_group_id = $newGroupId 
3774
                        WHERE 
3775
                            c_id = $courseId AND
3776
                            iid = $workIid
3777
                        ";
3778
                $connection->executeQuery($sql);
3779
            }
3780
        }
3781
    }
3782
3783
    error_log('End - Fix c_student_publication.post_group_id');
3784
3785
    // Delete c_student_publication from any session that doesn't exist anymore
3786
    $sql = "DELETE FROM c_student_publication 
3787
            WHERE session_id NOT IN (SELECT id FROM session) AND (session_id <> 0 AND session_id is not null)";
3788
    $connection->executeQuery($sql);
3789
3790
    error_log('Fix work documents');
3791
    // Fix work documents that don't have c_item_property value
3792
    $sql = "SELECT * FROM c_student_publication WHERE parent_id IS NOT NULL";
3793
    $statement = $connection->executeQuery($sql);
3794
    $result = $statement->fetchAll();
3795
    foreach ($result as $row) {
3796
        $groupId = $row['post_group_id'];
3797
        $courseId = $row['c_id'];
3798
        $sessionId = $row['session_id'];
3799
        $workId = $row['id'];
3800
        $itemInfo = api_get_item_property_info(
3801
            $courseId,
3802
            'work',
3803
            $workId,
3804
            $sessionId
3805
        );
3806
        $courseInfo = api_get_course_info_by_id($courseId);
3807
        if (empty($itemInfo)) {
3808
            api_item_property_update(
3809
                $courseInfo,
3810
                'work',
3811
                $workId,
3812
                'visible',
3813
                1,
3814
                $groupId,
3815
                null,
3816
                null,
3817
                null,
3818
                $sessionId
3819
            );
3820
        }
3821
    }
3822
    error_log('End - Fix work documents');
3823
}
3824