Passed
Push — master ( 2c1297...2ffb1a )
by Julito
10:51
created

migrateSwitch()   F

Complexity

Conditions 31
Paths 8812

Size

Total Lines 132
Code Lines 94

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 31
eloc 94
nc 8812
nop 3
dl 0
loc 132
rs 0
c 1
b 1
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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 false|resource, 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 $updatePath 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
        } elseif (file_exists($updatePath.'config/configuration.php')) {
549
            $updateFromConfigFile = 'config/configuration.php';
550
        } else {
551
            // Give up recovering.
552
            //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);
553
            return null;
554
        }
555
    }
556
557
    if (file_exists($updatePath.$updateFromConfigFile) &&
558
        !is_dir($updatePath.$updateFromConfigFile)
559
    ) {
560
        require $updatePath.$updateFromConfigFile;
561
        $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...
562
563
        return $config->get($param);
564
    }
565
566
    error_log('Config array could not be found in get_config_param()', 0);
567
568
    return null;
569
}
570
571
/*      DATABASE RELATED FUNCTIONS */
572
573
/**
574
 * Gets a configuration parameter from the database. Returns returns null on failure.
575
 *
576
 * @param string $param Name of param we want
577
 *
578
 * @return mixed The parameter value or null if not found
579
 */
580
function get_config_param_from_db($param = '')
581
{
582
    $param = Database::escape_string($param);
583
584
    if (($res = Database::query("SELECT * FROM settings_current WHERE variable = '$param'")) !== false) {
585
        if (Database::num_rows($res) > 0) {
586
            $row = Database::fetch_array($res);
587
588
            return $row['selected_value'];
589
        }
590
    }
591
592
    return null;
593
}
594
595
/**
596
 * Connect to the database and returns the entity manager.
597
 *
598
 * @param string $dbHostForm     DB host
599
 * @param string $dbUsernameForm DB username
600
 * @param string $dbPassForm     DB password
601
 * @param string $dbNameForm     DB name
602
 * @param int    $dbPortForm     DB port
603
 *
604
 * @return \Database
605
 */
606
function connectToDatabase(
607
    $dbHostForm,
608
    $dbUsernameForm,
609
    $dbPassForm,
610
    $dbNameForm,
611
    $dbPortForm = 3306
612
) {
613
    $dbParams = [
614
        'driver' => 'pdo_mysql',
615
        'host' => $dbHostForm,
616
        'port' => $dbPortForm,
617
        'user' => $dbUsernameForm,
618
        'password' => $dbPassForm,
619
        'dbname' => $dbNameForm,
620
    ];
621
622
    $database = new \Database();
623
    $database->connect($dbParams);
624
625
    return $database;
626
}
627
628
/*      DISPLAY FUNCTIONS */
629
630
/**
631
 * This function prints class=active_step $current_step=$param.
632
 *
633
 * @param int $param A step in the installer process
634
 *
635
 * @author Patrick Cool <[email protected]>, Ghent University
636
 */
637
function step_active($param)
638
{
639
    global $current_step;
640
    if ($param == $current_step) {
641
        echo 'active';
642
    }
643
}
644
645
/**
646
 * This function displays the Step X of Y -.
647
 *
648
 * @return string String that says 'Step X of Y' with the right values
649
 */
650
function display_step_sequence()
651
{
652
    global $current_step;
653
654
    return get_lang('Step'.$current_step).' &ndash; ';
655
}
656
657
/**
658
 * Displays a drop down box for selection the preferred language.
659
 */
660
function display_language_selection_box(
661
    $name = 'language_list',
662
    $default_language = 'english'
663
) {
664
    // Reading language list.
665
    $language_list = get_language_folder_list();
666
667
    // Sanity checks due to the possibility for customizations.
668
    if (!is_array($language_list) || empty($language_list)) {
669
        $language_list = ['en' => 'English'];
670
    }
671
672
    // Sorting again, if it is necessary.
673
    //asort($language_list);
674
675
    // More sanity checks.
676
    if (!array_key_exists($default_language, $language_list)) {
677
        if (array_key_exists('en', $language_list)) {
678
            $default_language = 'en';
679
        } else {
680
            $language_keys = array_keys($language_list);
681
            $default_language = $language_keys[0];
682
        }
683
    }
684
685
    // Displaying the box.
686
    $html = '';
687
    $html .= "\t\t<select class='selectpicker show-tick form-control' data-style=\"btn-select\" name=\"$name\">\n";
688
    foreach ($language_list as $key => $value) {
689
        if ($key == $default_language) {
690
            $option_end = ' selected="selected">';
691
        } else {
692
            $option_end = '>';
693
        }
694
        $html .= "\t\t\t<option value=\"$key\"$option_end";
695
        $html .= $value;
696
        $html .= "</option>\n";
697
    }
698
    $html .= "\t\t</select>\n";
699
700
    return $html;
701
}
702
703
/**
704
 * This function displays a language dropdown box so that the installatioin
705
 * can be done in the language of the user.
706
 */
707
function display_language_selection()
708
{
709
    ?>
710
        <div class="install-icon">
711
            <img width="150px;" src="chamilo-install.svg"/>
712
        </div>
713
        <h2 class="install-title">
714
            <?php echo display_step_sequence(); ?>
715
            <?php echo get_lang('InstallationLanguage'); ?>
716
        </h2>
717
        <form id="lang_form" method="post" action="<?php echo api_get_self(); ?>">
718
            <p><?php echo get_lang('PleaseSelectInstallationProcessLanguage'); ?>:</p>
719
            <div class="form-group">
720
                <?php echo display_language_selection_box('language_list', api_get_interface_language()); ?>
721
            </div>
722
            <button type="submit" name="step1" class="btn btn-success" value="<?php echo get_lang('Next'); ?>">
723
                <em class="fa fa-forward"> </em>
724
                <?php echo get_lang('Next'); ?>
725
            </button>
726
            <input type="hidden" name="is_executable" id="is_executable" value="-" />
727
        </form>
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 '<h2 class="install-title">'.display_step_sequence().get_lang('Requirements')."</h2>";
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 '<h4 class="install-subtitle">'.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="install-requirement">'.get_lang('ServerRequirementsInfo').'</div>';
783
    echo '<div class="table-responsive">';
784
    echo '<table class="table table-bordered">
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
863
    // RECOMMENDED SETTINGS
864
    // Note: these are the settings for Joomla, does this also apply for Chamilo?
865
    // Note: also add upload_max_filesize here so that large uploads are possible
866
    echo '<h4 class="install-subtitle">'.get_lang('RecommendedSettings').'</h4>';
867
    echo '<div class="install-requirement">'.get_lang('RecommendedSettingsInfo').'</div>';
868
    echo '<div class="table-responsive">';
869
    echo '<table class="table table-bordered">
870
            <tr>
871
                <th>'.get_lang('Setting').'</th>
872
                <th>'.get_lang('Recommended').'</th>
873
                <th>'.get_lang('Actual').'</th>
874
            </tr>
875
            
876
            <tr>
877
                <td class="requirements-item"><a href="http://php.net/manual/ref.errorfunc.php#ini.display-errors">Display Errors</a></td>
878
                <td class="requirements-recommended">'.Display::label('OFF', 'success').'</td>
879
                <td class="requirements-value">'.checkPhpSetting('display_errors', 'OFF').'</td>
880
            </tr>
881
            <tr>
882
                <td class="requirements-item"><a href="http://php.net/manual/ini.core.php#ini.file-uploads">File Uploads</a></td>
883
                <td class="requirements-recommended">'.Display::label('ON', 'success').'</td>
884
                <td class="requirements-value">'.checkPhpSetting('file_uploads', 'ON').'</td>
885
            </tr>
886
            <tr>
887
                <td class="requirements-item"><a href="http://php.net/manual/ref.session.php#ini.session.auto-start">Session auto start</a></td>
888
                <td class="requirements-recommended">'.Display::label('OFF', 'success').'</td>
889
                <td class="requirements-value">'.checkPhpSetting('session.auto_start', 'OFF').'</td>
890
            </tr>
891
            <tr>
892
                <td class="requirements-item"><a href="http://php.net/manual/ini.core.php#ini.short-open-tag">Short Open Tag</a></td>
893
                <td class="requirements-recommended">'.Display::label('OFF', 'success').'</td>
894
                <td class="requirements-value">'.checkPhpSetting('short_open_tag', 'OFF').'</td>
895
            </tr>
896
            <tr>
897
                <td class="requirements-item"><a href="http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-httponly">Cookie HTTP Only</a></td>
898
                <td class="requirements-recommended">'.Display::label('ON', 'success').'</td>
899
                <td class="requirements-value">'.checkPhpSetting('session.cookie_httponly', 'ON').'</td>
900
            </tr>
901
            <tr>
902
                <td class="requirements-item"><a href="http://php.net/manual/ini.core.php#ini.upload-max-filesize">Maximum upload file size</a></td>
903
                <td class="requirements-recommended">'.Display::label('>= '.REQUIRED_MIN_UPLOAD_MAX_FILESIZE.'M', 'success').'</td>
904
                <td class="requirements-value">'.compare_setting_values(ini_get('upload_max_filesize'), REQUIRED_MIN_UPLOAD_MAX_FILESIZE).'</td>
905
            </tr>
906
            <tr>
907
                <td class="requirements-item"><a href="http://php.net/manual/ini.core.php#ini.post-max-size">Maximum post size</a></td>
908
                <td class="requirements-recommended">'.Display::label('>= '.REQUIRED_MIN_POST_MAX_SIZE.'M', 'success').'</td>
909
                <td class="requirements-value">'.compare_setting_values(ini_get('post_max_size'), REQUIRED_MIN_POST_MAX_SIZE).'</td>
910
            </tr>
911
            <tr>
912
                <td class="requirements-item"><a href="http://www.php.net/manual/en/ini.core.php#ini.memory-limit">Memory Limit</a></td>
913
                <td class="requirements-recommended">'.Display::label('>= '.REQUIRED_MIN_MEMORY_LIMIT.'M', 'success').'</td>
914
                <td class="requirements-value">'.compare_setting_values($originalMemoryLimit, REQUIRED_MIN_MEMORY_LIMIT).'</td>
915
            </tr>
916
          </table>';
917
    echo '</div>';
918
919
    // DIRECTORY AND FILE PERMISSIONS
920
    echo '<h4 class="install-subtitle">'.get_lang('DirectoryAndFilePermissions').'</h4>';
921
    echo '<div class="install-requirement">'.get_lang('DirectoryAndFilePermissionsInfo').'</div>';
922
    echo '<div class="table-responsive">';
923
924
    $course_attempt_name = '__XxTestxX__';
925
    $course_dir = api_get_path(SYS_COURSE_PATH).$course_attempt_name;
926
    $fileToCreate = 'test.html';
927
    //Just in case
928
    @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

928
    /** @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...
929
    @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

929
    /** @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...
930
931
    $perms_dir = [0777, 0755, 0775, 0770, 0750, 0700];
932
    $perms_fil = [0666, 0644, 0664, 0660, 0640, 0600];
933
    $course_test_was_created = false;
934
    $dir_perm_verified = 0777;
935
    foreach ($perms_dir as $perm) {
936
        $r = @mkdir($course_dir, $perm);
937
        if ($r === true) {
938
            $dir_perm_verified = $perm;
939
            $course_test_was_created = true;
940
            break;
941
        }
942
    }
943
944
    $fil_perm_verified = 0666;
945
    $file_course_test_was_created = false;
946
    if (is_dir($course_dir)) {
947
        foreach ($perms_fil as $perm) {
948
            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...
949
                break;
950
            }
951
            $r = @touch($course_dir.'/'.$fileToCreate, $perm);
952
            if ($r === true) {
953
                $fil_perm_verified = $perm;
954
                if (checkCourseScriptCreation($course_dir, $course_attempt_name, $fileToCreate)) {
955
                    $file_course_test_was_created = true;
956
                }
957
            }
958
        }
959
    }
960
961
    @unlink($course_dir.'/'.$fileToCreate);
962
    @rmdir($course_dir);
963
964
    $_SESSION['permissions_for_new_directories'] = $_setting['permissions_for_new_directories'] = $dir_perm_verified;
965
    $_SESSION['permissions_for_new_files'] = $_setting['permissions_for_new_files'] = $fil_perm_verified;
966
967
    $dir_perm = Display::label('0'.decoct($dir_perm_verified), 'info');
968
    $file_perm = Display::label('0'.decoct($fil_perm_verified), 'info');
969
970
    $courseTestLabel = Display::label(get_lang('No'), 'important');
971
    if ($course_test_was_created && $file_course_test_was_created) {
972
        $courseTestLabel = Display::label(get_lang('Yes'), 'success');
973
    }
974
975
    if ($course_test_was_created && !$file_course_test_was_created) {
976
        $courseTestLabel = Display::label(get_lang('Warning'), 'warning');
977
        $courseTestLabel .= '<br />'.sprintf(
978
            get_lang('InstallWarningCouldNotInterpretPHP'),
979
            api_get_path(WEB_COURSE_PATH).$course_attempt_name.'/'.$fileToCreate
980
        );
981
    }
982
983
    if (!$course_test_was_created && !$file_course_test_was_created) {
984
        $courseTestLabel = Display::label(get_lang('No'), 'important');
985
    }
986
987
    $oldConf = '';
988
    if (file_exists(api_get_path(SYS_CODE_PATH).'inc/conf/configuration.php')) {
989
        $oldConf = '<tr>
990
            <td class="requirements-item">'.api_get_path(SYS_CODE_PATH).'inc/conf</td>
991
            <td class="requirements-value">'.check_writable(api_get_path(SYS_CODE_PATH).'inc/conf').'</td>
992
        </tr>';
993
    }
994
995
    echo '<table class="table table-bordered">
996
            '.$oldConf.'
997
            <tr>
998
                <td class="requirements-item">'.api_get_path(SYS_APP_PATH).'</td>
999
                <td class="requirements-value">'.check_writable(api_get_path(SYS_APP_PATH)).'</td>
1000
            </tr>
1001
            <tr>
1002
                <td class="requirements-item">'.api_get_path(SYS_PATH).'config</td>
1003
                <td class="requirements-value">'.check_writable(api_get_path(SYS_PATH).'config').'</td>
1004
            </tr>
1005
            <tr>
1006
                <td class="requirements-item">'.api_get_path(SYS_PATH).'vendor/</td>
1007
                <td class="requirements-value">'.checkReadable(api_get_path(SYS_PATH).'vendor').'</td>
1008
            </tr>
1009
            <tr>
1010
                <td class="requirements-item">'.api_get_path(SYS_PUBLIC_PATH).'</td>
1011
                <td class="requirements-value">'.check_writable(api_get_path(SYS_PUBLIC_PATH)).'</td>
1012
            </tr>
1013
            <tr>
1014
                <td class="requirements-item">'.get_lang('CourseTestWasCreated').'</td>
1015
                <td class="requirements-value">'.$courseTestLabel.' </td>
1016
            </tr>
1017
            <tr>
1018
                <td class="requirements-item">'.get_lang('PermissionsForNewDirs').'</td>
1019
                <td class="requirements-value">'.$dir_perm.' </td>
1020
            </tr>
1021
            <tr>
1022
                <td class="requirements-item">'.get_lang('PermissionsForNewFiles').'</td>
1023
                <td class="requirements-value">'.$file_perm.' </td>
1024
            </tr>
1025
        </table>';
1026
1027
    echo '</div>';
1028
1029
    if ($installType == 'update' && (empty($updatePath) || $badUpdatePath)) {
1030
        if ($badUpdatePath) {
1031
            ?>
1032
            <div class="alert alert-warning">
1033
                <?php echo get_lang('Error'); ?>!<br />
1034
                Chamilo <?php echo implode('|', $update_from_version_8).' '.get_lang('HasNotBeenFoundInThatDir'); ?>.
1035
            </div>
1036
        <?php
1037
        } else {
1038
            echo '<br />';
1039
        } ?>
1040
            <div class="row">
1041
                <div class="col-md-12">
1042
                    <p><?php echo get_lang('OldVersionRootPath'); ?>:
1043
                        <input type="text" name="updatePath" size="50" value="<?php echo ($badUpdatePath && !empty($updatePath)) ? htmlentities($updatePath) : ''; ?>" />
1044
                    </p>
1045
                    <p>
1046
                        <div class="btn-group">
1047
                            <button type="submit" class="btn btn-secondary" name="step1" value="<?php echo get_lang('Back'); ?>" >
1048
                                <em class="fa fa-backward"> <?php echo get_lang('Back'); ?></em>
1049
                            </button>
1050
                            <input type="hidden" name="is_executable" id="is_executable" value="-" />
1051
                            <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;" >
1052
                                <em class="fa fa-forward"> </em> <?php echo get_lang('Next'); ?>
1053
                            </button>
1054
                        </div>
1055
                    </p>
1056
                </div>
1057
            </div>
1058
1059
        <?php
1060
    } else {
1061
        $error = false;
1062
        // First, attempt to set writing permissions if we don't have them yet
1063
        $perm = api_get_permissions_for_new_directories();
1064
        $perm_file = api_get_permissions_for_new_files();
1065
        $notWritable = [];
1066
1067
        $checked_writable = api_get_path(SYS_APP_PATH);
1068
        if (!is_writable($checked_writable)) {
1069
            $notWritable[] = $checked_writable;
1070
            @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

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

1369
    /** @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...
1370
) {
1371
    //echo "<tr ".$tr_attribute.">";
1372
    echo "<label class='col-sm-4'>$parameterName</label>";
1373
1374
    if ($installType == INSTALL_TYPE_UPDATE && $displayWhenUpdate) {
1375
        echo '<input type="hidden" name="'.$formFieldName.'" id="'.$formFieldName.'" value="'.api_htmlentities($parameterValue).'" />'.$parameterValue;
1376
    } else {
1377
        $inputType = $formFieldName == 'dbPassForm' ? 'password' : 'text';
1378
1379
        //Slightly limit the length of the database prefix to avoid having to cut down the databases names later on
1380
        $maxLength = $formFieldName == 'dbPrefixForm' ? '15' : MAX_FORM_FIELD_LENGTH;
1381
        if ($installType == INSTALL_TYPE_UPDATE) {
1382
            echo '<input type="hidden" name="'.$formFieldName.'" id="'.$formFieldName.'" value="'.api_htmlentities($parameterValue).'" />';
1383
            echo api_htmlentities($parameterValue);
1384
        } else {
1385
            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>";
1386
            echo '<div class="col-sm-3">'.$extra_notice.'</div>';
1387
        }
1388
    }
1389
}
1390
1391
/**
1392
 * Displays step 3 - a form where the user can enter the installation settings
1393
 * regarding the databases - login and password, names, prefixes, single
1394
 * or multiple databases, tracking or not...
1395
 *
1396
 * @param string $installType
1397
 * @param string $dbHostForm
1398
 * @param string $dbUsernameForm
1399
 * @param string $dbPassForm
1400
 * @param string $dbNameForm
1401
 * @param int    $dbPortForm
1402
 * @param string $installationProfile
1403
 */
1404
function display_database_settings_form(
1405
    $installType,
1406
    $dbHostForm,
1407
    $dbUsernameForm,
1408
    $dbPassForm,
1409
    $dbNameForm,
1410
    $dbPortForm = 3306,
1411
    $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

1411
    /** @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...
1412
) {
1413
    if ($installType == 'update') {
1414
        global $_configuration;
1415
        $dbHostForm = $_configuration['db_host'];
1416
        $dbUsernameForm = $_configuration['db_user'];
1417
        $dbPassForm = $_configuration['db_password'];
1418
        $dbNameForm = $_configuration['main_database'];
1419
        $dbPortForm = isset($_configuration['db_port']) ? $_configuration['db_port'] : '';
1420
1421
        echo '<div class="RequirementHeading"><h2>'.display_step_sequence().get_lang('DBSetting').'</h2></div>';
1422
        echo '<div class="RequirementContent">';
1423
        echo get_lang('DBSettingUpgradeIntro');
1424
        echo '</div>';
1425
    } else {
1426
        echo '<div class="RequirementHeading"><h2>'.display_step_sequence().get_lang('DBSetting').'</h2></div>';
1427
        echo '<div class="RequirementContent">';
1428
        echo get_lang('DBSettingIntro');
1429
        echo '</div>';
1430
    } ?>
1431
    <div class="panel panel-default">
1432
        <div class="panel-body">
1433
        <div class="form-group">
1434
            <label class="col-sm-4"><?php echo get_lang('DBHost'); ?> </label>
1435
            <?php if ($installType == 'update') {
1436
        ?>
1437
            <div class="col-sm-5">
1438
                <input type="hidden" name="dbHostForm" value="<?php echo htmlentities($dbHostForm); ?>" /><?php echo $dbHostForm; ?>
1439
            </div>
1440
            <div class="col-sm-3"></div>
1441
            <?php
1442
    } else {
1443
        ?>
1444
            <div class="col-sm-5">
1445
                <input type="text" class="form-control" size="25" maxlength="50" name="dbHostForm" value="<?php echo htmlentities($dbHostForm); ?>" />
1446
            </div>
1447
            <div class="col-sm-3"><?php echo get_lang('EG').' localhost'; ?></div>
1448
            <?php
1449
    } ?>
1450
        </div>
1451
        <div class="form-group">
1452
            <label class="col-sm-4"><?php echo get_lang('DBPort'); ?> </label>
1453
            <?php if ($installType == 'update') {
1454
        ?>
1455
            <div class="col-sm-5">
1456
                <input type="hidden" name="dbPortForm" value="<?php echo htmlentities($dbPortForm); ?>" /><?php echo $dbPortForm; ?>
1457
            </div>
1458
            <div class="col-sm-3"></div>
1459
            <?php
1460
    } else {
1461
        ?>
1462
            <div class="col-sm-5">
1463
                <input type="text" class="form-control" size="25" maxlength="50" name="dbPortForm" value="<?php echo htmlentities($dbPortForm); ?>" />
1464
            </div>
1465
            <div class="col-sm-3"><?php echo get_lang('EG').' 3306'; ?></div>
1466
            <?php
1467
    } ?>
1468
        </div>
1469
        <div class="form-group">
1470
            <?php
1471
                //database user username
1472
                $example_login = get_lang('EG').' root';
1473
    displayDatabaseParameter($installType, get_lang('DBLogin'), 'dbUsernameForm', $dbUsernameForm, $example_login); ?>
1474
        </div>
1475
        <div class="form-group">
1476
            <?php
1477
            //database user password
1478
            $example_password = get_lang('EG').' '.api_generate_password();
1479
    displayDatabaseParameter($installType, get_lang('DBPassword'), 'dbPassForm', $dbPassForm, $example_password); ?>
1480
        </div>
1481
        <div class="form-group">
1482
            <?php
1483
            //Database Name fix replace weird chars
1484
            if ($installType != INSTALL_TYPE_UPDATE) {
1485
                $dbNameForm = str_replace(['-', '*', '$', ' ', '.'], '', $dbNameForm);
1486
            }
1487
1488
    displayDatabaseParameter(
1489
                $installType,
1490
                get_lang('MainDB'),
1491
                'dbNameForm',
1492
                $dbNameForm,
1493
                '&nbsp;',
1494
                null,
1495
                'id="optional_param1"'
1496
                ); ?>
1497
        </div>
1498
       <?php if ($installType != INSTALL_TYPE_UPDATE) {
1499
                    ?>
1500
        <div class="form-group">
1501
            <div class="col-sm-3"></div>
1502
            <div class="col-sm-9">
1503
            <button type="submit" class="btn btn-primary" name="step3" value="step3">
1504
                <em class="fa fa-refresh"> </em>
1505
                <?php echo get_lang('CheckDatabaseConnection'); ?>
1506
            </button>
1507
            </div>
1508
        </div>
1509
        <?php
1510
                } ?>
1511
1512
        </div>
1513
    </div>
1514
    <?php
1515
        $database_exists_text = '';
1516
    $manager = null;
1517
    try {
1518
        if ($installType === 'update') {
1519
            /** @var \Database $manager */
1520
            $manager = connectToDatabase(
1521
                $dbHostForm,
1522
                $dbUsernameForm,
1523
                $dbPassForm,
1524
                $dbNameForm,
1525
                $dbPortForm
1526
            );
1527
1528
            $connection = $manager->getConnection();
1529
            $connection->connect();
1530
            $schemaManager = $connection->getSchemaManager();
1531
1532
            // Test create/alter/drop table
1533
            $table = 'zXxTESTxX_'.mt_rand(0, 1000);
1534
            $sql = "CREATE TABLE $table (id INT AUTO_INCREMENT NOT NULL, name varchar(255), PRIMARY KEY(id))";
1535
            $connection->query($sql);
1536
            $tableCreationWorks = false;
1537
            $tableDropWorks = false;
1538
            if ($schemaManager->tablesExist($table)) {
1539
                $tableCreationWorks = true;
1540
                $sql = "ALTER TABLE $table ADD COLUMN name2 varchar(140) ";
1541
                $connection->query($sql);
1542
                $schemaManager->dropTable($table);
1543
                $tableDropWorks = $schemaManager->tablesExist($table) === false;
1544
            }
1545
        } else {
1546
            $manager = connectToDatabase(
1547
                $dbHostForm,
1548
                $dbUsernameForm,
1549
                $dbPassForm,
1550
                null,
1551
                $dbPortForm
1552
            );
1553
1554
            $schemaManager = $manager->getConnection()->getSchemaManager();
1555
            $databases = $schemaManager->listDatabases();
1556
            if (in_array($dbNameForm, $databases)) {
1557
                $database_exists_text = '<div class="alert alert-warning">'.get_lang('ADatabaseWithTheSameNameAlreadyExists').'</div>';
1558
            }
1559
        }
1560
    } catch (Exception $e) {
1561
        $database_exists_text = $e->getMessage();
1562
        $manager = false;
1563
    }
1564
1565
    if ($manager && $manager->getConnection()->isConnected()): ?>
1566
        <?php echo $database_exists_text; ?>
1567
        <div id="db_status" class="alert alert-success">
1568
            Database host: <strong><?php echo $manager->getConnection()->getHost(); ?></strong><br/>
1569
            Database port: <strong><?php echo $manager->getConnection()->getPort(); ?></strong><br/>
1570
            Database driver: <strong><?php echo $manager->getConnection()->getDriver()->getName(); ?></strong><br/>
1571
            <?php
1572
                if ($installType === 'update') {
1573
                    echo get_lang('CreateTableWorks').' <strong>Ok</strong>';
1574
                    echo '<br/ >';
1575
                    echo get_lang('AlterTableWorks').' <strong>Ok</strong>';
1576
                    echo '<br/ >';
1577
                    echo get_lang('DropColumnWorks').' <strong>Ok</strong>';
1578
                } ?>
1579
        </div>
1580
    <?php else: ?>
1581
        <div id="db_status" class="alert alert-danger">
1582
            <p><?php echo get_lang('FailedConectionDatabase'); ?></strong></p>
1583
            <code><?php echo $database_exists_text; ?></code>
1584
        </div>
1585
    <?php endif; ?>
1586
1587
   <div class="btn-group" role="group">
1588
       <button type="submit" name="step2"
1589
               class="btn btn-secondary pull-right" value="&lt; <?php echo get_lang('Previous'); ?>" >
1590
           <em class="fa fa-backward"> </em> <?php echo get_lang('Previous'); ?>
1591
       </button>
1592
       <input type="hidden" name="is_executable" id="is_executable" value="-" />
1593
       <?php if ($manager) {
1594
                    ?>
1595
           <button type="submit" class="btn btn-success" name="step4" value="<?php echo get_lang('Next'); ?> &gt;" >
1596
               <em class="fa fa-forward"> </em> <?php echo get_lang('Next'); ?>
1597
           </button>
1598
       <?php
1599
                } else {
1600
                    ?>
1601
           <button
1602
                   disabled="disabled"
1603
                   type="submit" class="btn btn-success disabled" name="step4" value="<?php echo get_lang('Next'); ?> &gt;" >
1604
               <em class="fa fa-forward"> </em> <?php echo get_lang('Next'); ?>
1605
           </button>
1606
       <?php
1607
                } ?>
1608
   </div>
1609
    <?php
1610
}
1611
1612
function panel($content = null, $title = null, $id = null, $style = null)
1613
{
1614
    $html = '';
1615
    if (empty($style)) {
1616
        $style = 'default';
1617
    }
1618
    if (!empty($title)) {
1619
        $panelTitle = Display::div($title, ['class' => 'panel-heading']);
1620
        $panelBody = Display::div($content, ['class' => 'panel-body']);
1621
        $panelParent = Display::div($panelTitle.$panelBody, ['id' => $id, 'class' => 'panel panel-'.$style]);
1622
    } else {
1623
        $panelBody = Display::div($html, ['class' => 'panel-body']);
1624
        $panelParent = Display::div($panelBody, ['id' => $id, 'class' => 'panel panel-'.$style]);
1625
    }
1626
    $html .= $panelParent;
1627
1628
    return $html;
1629
}
1630
1631
/**
1632
 * Displays a parameter in a table row.
1633
 * Used by the display_configuration_settings_form function.
1634
 *
1635
 * @param string $installType
1636
 * @param string $parameterName
1637
 * @param string $formFieldName
1638
 * @param string $parameterValue
1639
 * @param string $displayWhenUpdate
1640
 *
1641
 * @return string
1642
 */
1643
function display_configuration_parameter(
1644
    $installType,
1645
    $parameterName,
1646
    $formFieldName,
1647
    $parameterValue,
1648
    $displayWhenUpdate = 'true'
1649
) {
1650
    $html = '<div class="form-group">';
1651
    $html .= '<label class="col-sm-6 control-label">'.$parameterName.'</label>';
1652
    if ($installType == INSTALL_TYPE_UPDATE && $displayWhenUpdate) {
1653
        $html .= '<input type="hidden" name="'.$formFieldName.'" value="'.api_htmlentities($parameterValue, ENT_QUOTES).'" />'.$parameterValue;
1654
    } else {
1655
        $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>";
1656
    }
1657
    $html .= "</div>";
1658
1659
    return $html;
1660
}
1661
1662
/**
1663
 * Displays step 4 of the installation - configuration settings about Chamilo itself.
1664
 *
1665
 * @param string $installType
1666
 * @param string $urlForm
1667
 * @param string $languageForm
1668
 * @param string $emailForm
1669
 * @param string $adminFirstName
1670
 * @param string $adminLastName
1671
 * @param string $adminPhoneForm
1672
 * @param string $campusForm
1673
 * @param string $institutionForm
1674
 * @param string $institutionUrlForm
1675
 * @param string $encryptPassForm
1676
 * @param bool   $allowSelfReg
1677
 * @param bool   $allowSelfRegProf
1678
 * @param string $loginForm
1679
 * @param string $passForm
1680
 */
1681
function display_configuration_settings_form(
1682
    $installType,
1683
    $urlForm,
1684
    $languageForm,
1685
    $emailForm,
1686
    $adminFirstName,
1687
    $adminLastName,
1688
    $adminPhoneForm,
1689
    $campusForm,
1690
    $institutionForm,
1691
    $institutionUrlForm,
1692
    $encryptPassForm,
1693
    $allowSelfReg,
1694
    $allowSelfRegProf,
1695
    $loginForm,
1696
    $passForm
1697
) {
1698
    if ($installType != 'update' && empty($languageForm)) {
1699
        $languageForm = $_SESSION['install_language'];
1700
    }
1701
    echo '<div class="RequirementHeading">';
1702
    echo "<h2>".display_step_sequence().get_lang("CfgSetting")."</h2>";
1703
    echo '</div>';
1704
1705
    echo '<p>'.get_lang('ConfigSettingsInfo').' <strong>app/config/configuration.php</strong></p>';
1706
1707
    // Parameter 1: administrator's login
1708
    $html = '';
1709
    $html .= display_configuration_parameter(
1710
        $installType,
1711
        get_lang('AdminLogin'),
1712
        'loginForm',
1713
        $loginForm,
1714
        $installType == 'update'
1715
    );
1716
1717
    // Parameter 2: administrator's password
1718
    if ($installType != 'update') {
1719
        $html .= display_configuration_parameter($installType, get_lang('AdminPass'), 'passForm', $passForm, false);
1720
    }
1721
1722
    // Parameters 3 and 4: administrator's names
1723
1724
    $html .= display_configuration_parameter(
1725
        $installType,
1726
        get_lang('AdminFirstName'),
1727
        'adminFirstName',
1728
        $adminFirstName
1729
    );
1730
    $html .= display_configuration_parameter($installType, get_lang('AdminLastName'), 'adminLastName', $adminLastName);
1731
1732
    //Parameter 3: administrator's email
1733
    $html .= display_configuration_parameter($installType, get_lang('AdminEmail'), 'emailForm', $emailForm);
1734
1735
    //Parameter 6: administrator's telephone
1736
    $html .= display_configuration_parameter($installType, get_lang('AdminPhone'), 'adminPhoneForm', $adminPhoneForm);
1737
    echo panel($html, get_lang('Administrator'), 'administrator');
1738
1739
    //First parameter: language
1740
    $html = '<div class="form-group">';
1741
    $html .= '<label class="col-sm-6 control-label">'.get_lang('MainLang')."</label>";
1742
    if ($installType == 'update') {
1743
        $html .= '<input type="hidden" name="languageForm" value="'.api_htmlentities($languageForm, ENT_QUOTES).'" />'.$languageForm;
1744
    } else { // new installation
1745
        $html .= '<div class="col-sm-6">';
1746
        $html .= display_language_selection_box('languageForm', $languageForm);
1747
        $html .= '</div>';
1748
    }
1749
    $html .= "</div>";
1750
1751
    //Second parameter: Chamilo URL
1752
    $html .= '<div class="form-group">';
1753
    $html .= '<label class="col-sm-6 control-label">'.get_lang('ChamiloURL').get_lang('ThisFieldIsRequired').'</label>';
1754
1755
    if ($installType == 'update') {
1756
        $html .= api_htmlentities($urlForm, ENT_QUOTES)."\n";
1757
    } else {
1758
        $html .= '<div class="col-sm-6">';
1759
        $html .= '<input class="form-control" type="text" size="40" maxlength="100" name="urlForm" value="'.api_htmlentities($urlForm, ENT_QUOTES).'" />';
1760
        $html .= '</div>';
1761
    }
1762
    $html .= '</div>';
1763
1764
    //Parameter 9: campus name
1765
    $html .= display_configuration_parameter(
1766
        $installType,
1767
        get_lang('CampusName'),
1768
        'campusForm',
1769
        $campusForm
1770
    );
1771
1772
    //Parameter 10: institute (short) name
1773
    $html .= display_configuration_parameter(
1774
        $installType,
1775
        get_lang('InstituteShortName'),
1776
        'institutionForm',
1777
        $institutionForm
1778
    );
1779
1780
    //Parameter 11: institute (short) name
1781
    $html .= display_configuration_parameter(
1782
        $installType,
1783
        get_lang('InstituteURL'),
1784
        'institutionUrlForm',
1785
        $institutionUrlForm
1786
    );
1787
1788
    $html .= '<div class="form-group">
1789
            <label class="col-sm-6 control-label">'.get_lang("EncryptMethodUserPass").'</label>
1790
        <div class="col-sm-6">';
1791
    if ($installType == 'update') {
1792
        $html .= '<input type="hidden" name="encryptPassForm" value="'.$encryptPassForm.'" />'.$encryptPassForm;
1793
    } else {
1794
        $html .= '<div class="checkbox">
1795
                    <label>
1796
                        <input  type="radio" name="encryptPassForm" value="bcrypt" id="encryptPass1" '.($encryptPassForm == 'bcrypt' ? 'checked="checked" ' : '').'/> bcrypt
1797
                    </label>';
1798
1799
        $html .= '<label>
1800
                        <input  type="radio" name="encryptPassForm" value="sha1" id="encryptPass1" '.($encryptPassForm == 'sha1' ? 'checked="checked" ' : '').'/> sha1
1801
                    </label>';
1802
1803
        $html .= '<label>
1804
                        <input type="radio" name="encryptPassForm" value="md5" id="encryptPass0" '.($encryptPassForm == 'md5' ? 'checked="checked" ' : '').'/> md5
1805
                    </label>';
1806
1807
        $html .= '<label>
1808
                        <input type="radio" name="encryptPassForm" value="none" id="encryptPass2" '.($encryptPassForm == 'none' ? 'checked="checked" ' : '').'/>'.get_lang('None').'
1809
                    </label>';
1810
        $html .= '</div>';
1811
    }
1812
    $html .= '</div></div>';
1813
1814
    $html .= '<div class="form-group">
1815
            <label class="col-sm-6 control-label">'.get_lang('AllowSelfReg').'</label>
1816
            <div class="col-sm-6">';
1817
    if ($installType == 'update') {
1818
        if ($allowSelfReg == 'true') {
1819
            $label = get_lang('Yes');
1820
        } elseif ($allowSelfReg == 'false') {
1821
            $label = get_lang('No');
1822
        } else {
1823
            $label = get_lang('AfterApproval');
1824
        }
1825
        $html .= '<input type="hidden" name="allowSelfReg" value="'.$allowSelfReg.'" />'.$label;
1826
    } else {
1827
        $html .= '<div class="control-group">';
1828
        $html .= '<label class="checkbox-inline">
1829
                        <input type="radio" name="allowSelfReg" value="true" id="allowSelfReg1" '.($allowSelfReg == 'true' ? 'checked="checked" ' : '').' /> '.get_lang('Yes').'
1830
                    </label>';
1831
        $html .= '<label class="checkbox-inline">
1832
                        <input type="radio" name="allowSelfReg" value="false" id="allowSelfReg0" '.($allowSelfReg == 'false' ? '' : 'checked="checked" ').' /> '.get_lang('No').'
1833
                    </label>';
1834
        $html .= '<label class="checkbox-inline">
1835
                    <input type="radio" name="allowSelfReg" value="approval" id="allowSelfReg2" '.($allowSelfReg == 'approval' ? '' : 'checked="checked" ').' /> '.get_lang('AfterApproval').'
1836
                </label>';
1837
        $html .= '</div>';
1838
    }
1839
    $html .= '</div>';
1840
    $html .= '</div>';
1841
1842
    $html .= '<div class="form-group">';
1843
    $html .= '<label class="col-sm-6 control-label">'.get_lang('AllowSelfRegProf').'</label>
1844
        <div class="col-sm-6">';
1845
    if ($installType == 'update') {
1846
        if ($allowSelfRegProf == 'true') {
1847
            $label = get_lang('Yes');
1848
        } else {
1849
            $label = get_lang('No');
1850
        }
1851
        $html .= '<input type="hidden" name="allowSelfRegProf" value="'.$allowSelfRegProf.'" />'.$label;
1852
    } else {
1853
        $html .= '<div class="control-group">
1854
                <label class="checkbox-inline">
1855
                    <input type="radio" name="allowSelfRegProf" value="1" id="allowSelfRegProf1" '.($allowSelfRegProf ? 'checked="checked" ' : '').'/>
1856
                '.get_lang('Yes').'
1857
                </label>';
1858
        $html .= '<label class="checkbox-inline">
1859
                    <input type="radio" name="allowSelfRegProf" value="0" id="allowSelfRegProf0" '.($allowSelfRegProf ? '' : 'checked="checked" ').' />
1860
                   '.get_lang('No').'
1861
                </label>';
1862
        $html .= '</div>';
1863
    }
1864
    $html .= '</div>
1865
    </div>';
1866
1867
    echo panel($html, get_lang('Platform'), 'platform'); ?>
1868
    <div class='btn-group'>
1869
        <button type="submit" class="btn btn-secondary pull-right" name="step3" value="&lt; <?php echo get_lang('Previous'); ?>" ><em class="fa fa-backward"> </em> <?php echo get_lang('Previous'); ?></button>
1870
        <input type="hidden" name="is_executable" id="is_executable" value="-" />
1871
        <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>
1872
    </div>
1873
1874
    <?php
1875
}
1876
1877
/**
1878
 * After installation is completed (step 6), this message is displayed.
1879
 */
1880
function display_after_install_message()
1881
{
1882
    $html = '<div class="RequirementContent">'.get_lang('FirstUseTip').'</div>';
1883
    $html .= '<div class="alert alert-warning">';
1884
    $html .= '<strong>'.get_lang('SecurityAdvice').'</strong>';
1885
    $html .= ': ';
1886
    $html .= sprintf(get_lang('ToProtectYourSiteMakeXReadOnlyAndDeleteY'), 'app/config/', 'main/install/');
1887
    $html .= '</div></form>
1888
    <br />
1889
    <a class="btn btn-success btn-block" href="../../index.php">
1890
        '.get_lang('GoToYourNewlyCreatedPortal').'
1891
    </a>';
1892
1893
    return $html;
1894
}
1895
1896
/**
1897
 * This function return countries list from array (hardcoded).
1898
 *
1899
 * @param bool $combo (Optional) True for returning countries list with select html
1900
 *
1901
 * @return array|string countries list
1902
 */
1903
function get_countries_list_from_array($combo = false)
1904
{
1905
    $a_countries = [
1906
        "Afghanistan", "Albania", "Algeria", "Andorra", "Angola", "Antigua and Barbuda", "Argentina", "Armenia", "Australia", "Austria", "Azerbaijan",
1907
        "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana", "Brazil", "Brunei", "Bulgaria", "Burkina Faso", "Burundi",
1908
        "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",
1909
        "Denmark", "Djibouti", "Dominica", "Dominican Republic",
1910
        "East Timor (Timor Timur)", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia",
1911
        "Fiji", "Finland", "France",
1912
        "Gabon", "Gambia, The", "Georgia", "Germany", "Ghana", "Greece", "Grenada", "Guatemala", "Guinea", "Guinea-Bissau", "Guyana",
1913
        "Haiti", "Honduras", "Hungary",
1914
        "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy",
1915
        "Jamaica", "Japan", "Jordan",
1916
        "Kazakhstan", "Kenya", "Kiribati", "Korea, North", "Korea, South", "Kuwait", "Kyrgyzstan",
1917
        "Laos", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
1918
        "Macedonia", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Mauritania", "Mauritius", "Mexico", "Micronesia", "Moldova", "Monaco", "Mongolia", "Morocco", "Mozambique", "Myanmar",
1919
        "Namibia", "Nauru", "Nepa", "Netherlands", "New Zealand", "Nicaragua", "Niger", "Nigeria", "Norway",
1920
        "Oman",
1921
        "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Poland", "Portugal",
1922
        "Qatar",
1923
        "Romania", "Russia", "Rwanda",
1924
        "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",
1925
        "Taiwan", "Tajikistan", "Tanzania", "Thailand", "Togo", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan", "Tuvalu",
1926
        "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", "United States", "Uruguay", "Uzbekistan",
1927
        "Vanuatu", "Vatican City", "Venezuela", "Vietnam",
1928
        "Yemen",
1929
        "Zambia", "Zimbabwe",
1930
    ];
1931
    if ($combo) {
1932
        $country_select = '<select class="selectpicker show-tick" id="country" name="country">';
1933
        $country_select .= '<option value="">--- '.get_lang('SelectOne').' ---</option>';
1934
        foreach ($a_countries as $country) {
1935
            $country_select .= '<option value="'.$country.'">'.$country.'</option>';
1936
        }
1937
        $country_select .= '</select>';
1938
1939
        return $country_select;
1940
    }
1941
1942
    return $a_countries;
1943
}
1944
1945
/**
1946
 * Lock settings that can't be changed in other portals.
1947
 */
1948
function lockSettings()
1949
{
1950
    $settings = api_get_locked_settings();
1951
    $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
1952
    foreach ($settings as $setting) {
1953
        $sql = "UPDATE $table SET access_url_locked = 1 WHERE variable  = '$setting'";
1954
        Database::query($sql);
1955
    }
1956
}
1957
1958
/**
1959
 * Update dir values.
1960
 */
1961
function updateDirAndFilesPermissions()
1962
{
1963
    $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
1964
    $permissions_for_new_directories = isset($_SESSION['permissions_for_new_directories']) ? $_SESSION['permissions_for_new_directories'] : 0770;
1965
    $permissions_for_new_files = isset($_SESSION['permissions_for_new_files']) ? $_SESSION['permissions_for_new_files'] : 0660;
1966
    // use decoct() to store as string
1967
    Database::update(
1968
        $table,
1969
        ['selected_value' => '0'.decoct($permissions_for_new_directories)],
1970
        ['variable = ?' => 'permissions_for_new_directories']
1971
    );
1972
1973
    Database::update(
1974
        $table,
1975
        ['selected_value' => '0'.decoct($permissions_for_new_files)],
1976
        ['variable = ?' => 'permissions_for_new_files']
1977
    );
1978
1979
    if (isset($_SESSION['permissions_for_new_directories'])) {
1980
        unset($_SESSION['permissions_for_new_directories']);
1981
    }
1982
1983
    if (isset($_SESSION['permissions_for_new_files'])) {
1984
        unset($_SESSION['permissions_for_new_files']);
1985
    }
1986
}
1987
1988
/**
1989
 * @param $current_value
1990
 * @param $wanted_value
1991
 *
1992
 * @return string
1993
 */
1994
function compare_setting_values($current_value, $wanted_value)
1995
{
1996
    $current_value_string = $current_value;
1997
    $current_value = (float) $current_value;
1998
    $wanted_value = (float) $wanted_value;
1999
2000
    if ($current_value >= $wanted_value) {
2001
        return Display::label($current_value_string, 'success');
2002
    } else {
2003
        return Display::label($current_value_string, 'important');
2004
    }
2005
}
2006
2007
/**
2008
 * @param string $course_dir
2009
 * @param string $course_attempt_name
2010
 * @param string $file
2011
 *
2012
 * @return bool
2013
 */
2014
function checkCourseScriptCreation(
2015
    $course_dir,
2016
    $course_attempt_name,
2017
    $file
2018
) {
2019
    $output = false;
2020
    //Write in file
2021
    $file_name = $course_dir.'/'.$file;
2022
    $content = '123';
2023
2024
    if (is_writable($file_name)) {
2025
        if ($handler = @fopen($file_name, 'w')) {
2026
            //write content
2027
            if (fwrite($handler, $content)) {
2028
                $sock_errno = '';
2029
                $sock_errmsg = '';
2030
                $url = api_get_path(WEB_PATH).'app/courses/'.$course_attempt_name.'/'.$file;
2031
2032
                $parsed_url = parse_url($url);
2033
                //$scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'] : ''; //http
2034
                $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
2035
                // Patch if the host is the default host and is used through
2036
                // the IP address (sometimes the host is not taken correctly
2037
                // in this case)
2038
                if (empty($host) && !empty($_SERVER['HTTP_HOST'])) {
2039
                    $host = $_SERVER['HTTP_HOST'];
2040
                    $url = preg_replace('#:///#', '://'.$host.'/', $url);
2041
                }
2042
                $path = isset($parsed_url['path']) ? $parsed_url['path'] : '/';
2043
                $port = '';
2044
                $scheme = '';
2045
                switch ($parsed_url['scheme']) {
2046
                    case 'https':
2047
                        $scheme = 'ssl://';
2048
                        $port = 443;
2049
                        break;
2050
                    case 'http':
2051
                    default:
2052
                        $scheme = '';
2053
                        $port = 80;
2054
                }
2055
2056
                //Check fsockopen (not sure it works with https). If that is your case, you might want to try the
2057
                // suggestion at https://support.chamilo.org/issues/8260#note-3 (although it ignores SSL peer checks)
2058
                if ($fp = @fsockopen(str_replace('http://', $scheme, $url), $port, $sock_errno, $sock_errmsg, 60)) {
2059
                    $out = "GET $path HTTP/1.1\r\n";
2060
                    $out .= "Host: $host\r\n";
2061
                    $out .= "Connection: Close\r\n\r\n";
2062
2063
                    fwrite($fp, $out);
2064
                    while (!feof($fp)) {
2065
                        $result = str_replace("\r\n", '', fgets($fp, 128));
2066
                        if (!empty($result) && $result == '123') {
2067
                            $output = true;
2068
                        }
2069
                    }
2070
                    fclose($fp);
2071
                } elseif (ini_get('allow_url_fopen')) {
2072
                    // Check allow_url_fopen
2073
                    if ($fp = @fopen($url, 'r')) {
2074
                        while ($result = fgets($fp, 1024)) {
2075
                            if (!empty($result) && $result == '123') {
2076
                                $output = true;
2077
                            }
2078
                        }
2079
                        fclose($fp);
2080
                    }
2081
                } elseif (function_exists('curl_init')) {
2082
                    // Check if has support for cURL
2083
                    $ch = curl_init();
2084
                    curl_setopt($ch, CURLOPT_HEADER, 0);
2085
                    curl_setopt($ch, CURLOPT_URL, $url);
2086
                    //curl_setopt($ch, CURLOPT_TIMEOUT, 30);
2087
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
2088
                    $result = curl_exec($ch);
2089
                    if (!empty($result) && $result == '123') {
2090
                        $output = true;
2091
                    }
2092
                    curl_close($ch);
2093
                }
2094
            }
2095
            @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

2095
            /** @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...
2096
        }
2097
    }
2098
2099
    return $output;
2100
}
2101
2102
/**
2103
 * Save settings values.
2104
 *
2105
 * @param string $organizationName
2106
 * @param string $organizationUrl
2107
 * @param string $siteName
2108
 * @param string $adminEmail
2109
 * @param string $adminLastName
2110
 * @param string $adminFirstName
2111
 * @param string $language
2112
 * @param string $allowRegistration
2113
 * @param string $allowTeacherSelfRegistration
2114
 * @param string $installationProfile          The name of an installation profile file in main/install/profiles/
2115
 */
2116
function installSettings(
2117
    $organizationName,
2118
    $organizationUrl,
2119
    $siteName,
2120
    $adminEmail,
2121
    $adminLastName,
2122
    $adminFirstName,
2123
    $language,
2124
    $allowRegistration,
2125
    $allowTeacherSelfRegistration,
2126
    $installationProfile = ''
2127
) {
2128
    $allowTeacherSelfRegistration = $allowTeacherSelfRegistration ? 'true' : 'false';
2129
2130
    $settings = [
2131
        'institution' => $organizationName,
2132
        'institution_url' => $organizationUrl,
2133
        'site_name' => $siteName,
2134
        'administrator_email' => $adminEmail,
2135
        'administrator_surname' => $adminLastName,
2136
        'administrator_name' => $adminFirstName,
2137
        'platform_language' => $language,
2138
        'allow_registration' => $allowRegistration,
2139
        'allow_registration_as_teacher' => $allowTeacherSelfRegistration,
2140
    ];
2141
2142
    foreach ($settings as $variable => $value) {
2143
        $sql = "UPDATE settings_current
2144
                SET selected_value = '$value'
2145
                WHERE variable = '$variable'";
2146
        Database::query($sql);
2147
    }
2148
    installProfileSettings($installationProfile);
2149
}
2150
2151
/**
2152
 * Executes DB changes based in the classes defined in
2153
 * src/CoreBundle/Migrations/Schema/*.
2154
 *
2155
 * @param string        $chamiloVersion
2156
 * @param EntityManager $manager
2157
 *
2158
 * @throws \Doctrine\DBAL\DBALException
2159
 *
2160
 * @return bool
2161
 */
2162
function migrate($chamiloVersion, EntityManager $manager)
2163
{
2164
    $debug = true;
2165
    $connection = $manager->getConnection();
2166
2167
    $config = new \Doctrine\DBAL\Migrations\Configuration\Configuration($connection);
2168
2169
    // Table name that will store migrations log (will be created automatically,
2170
    // default name is: doctrine_migration_versions)
2171
    $config->setMigrationsTableName('version');
2172
    // Namespace of your migration classes, do not forget escape slashes, do not add last slash
2173
    $config->setMigrationsNamespace('Chamilo\CoreBundle\Migrations\Schema\V'.$chamiloVersion);
2174
    // Directory where your migrations are located
2175
    $versionPath = api_get_path(SYS_PATH).'src/CoreBundle/Migrations/Schema/V'.$chamiloVersion;
2176
    error_log("Reading files from dir: $versionPath");
2177
    $config->setMigrationsDirectory($versionPath);
2178
    // Load your migrations
2179
    $config->registerMigrationsFromDirectory($config->getMigrationsDirectory());
2180
2181
    $migration = new \Doctrine\DBAL\Migrations\Migration($config);
2182
    $versions = $config->getMigrations();
2183
2184
    /** @var Doctrine\DBAL\Migrations\Version $migrationItem */
2185
    foreach ($versions as $version) {
2186
        $version->getMigration()->setEntityManager($manager);
2187
    }
2188
2189
    $to = null; // if $to == null then schema will be migrated to latest version
2190
2191
    echo "<pre>";
2192
    try {
2193
        // Execute migration!
2194
        $migratedSQL = $migration->migrate($to);
2195
2196
        if ($debug) {
2197
            foreach ($migratedSQL as $version => $sqlList) {
2198
                echo "VERSION: $version<br>";
2199
                echo "----------------------------------------------<br>";
2200
                $total = count($sqlList);
2201
                error_log("VERSION: $version");
2202
                error_log("# queries: ".$total);
2203
                $counter = 1;
2204
                foreach ($sqlList as $sql) {
2205
                    echo "<code>$sql</code><br>";
2206
                    error_log("$counter/$total : $sql");
2207
                    $counter++;
2208
                }
2209
            }
2210
2211
            echo "<br>DONE!<br>";
2212
        }
2213
2214
        return true;
2215
    } catch (Exception $ex) {
2216
        if ($debug) {
2217
            echo "ERROR: {$ex->getMessage()}<br>";
2218
2219
            return false;
2220
        }
2221
    }
2222
2223
    echo "</pre>";
2224
2225
    return false;
2226
}
2227
2228
/**
2229
 * @param EntityManager $em
2230
 *
2231
 * @throws \Doctrine\DBAL\DBALException
2232
 */
2233
function fixIds(EntityManager $em)
2234
{
2235
    $connection = $em->getConnection();
2236
    $database = new Database();
2237
    $database->setManager($em);
2238
    $debug = true;
2239
    if ($debug) {
2240
        error_log('fixIds');
2241
    }
2242
2243
    // Create temporary indexes to increase speed of the following operations
2244
    // Adding and removing indexes will usually take much less time than
2245
    // the execution without indexes of the queries in this function, particularly
2246
    // for large tables
2247
    $sql = "ALTER TABLE c_document ADD INDEX tmpidx_doc(c_id, id)";
2248
    $connection->executeQuery($sql);
2249
    $sql = "ALTER TABLE c_student_publication ADD INDEX tmpidx_stud (c_id, id)";
2250
    $connection->executeQuery($sql);
2251
    $sql = "ALTER TABLE c_quiz ADD INDEX tmpidx_quiz (c_id, id)";
2252
    $connection->executeQuery($sql);
2253
    $sql = "ALTER TABLE c_item_property ADD INDEX tmpidx_ip (to_group_id)";
2254
    $connection->executeQuery($sql);
2255
2256
    $sql = "SELECT * FROM c_lp_item";
2257
    $result = $connection->fetchAll($sql);
2258
    foreach ($result as $item) {
2259
        $courseId = $item['c_id'];
2260
        $iid = isset($item['iid']) ? intval($item['iid']) : 0;
2261
        $ref = isset($item['ref']) ? intval($item['ref']) : 0;
2262
        $sql = null;
2263
2264
        $newId = '';
2265
2266
        switch ($item['item_type']) {
2267
            case TOOL_LINK:
2268
                $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref";
2269
                $data = $connection->fetchAssoc($sql);
2270
                if ($data) {
2271
                    $newId = $data['iid'];
2272
                }
2273
                break;
2274
            case TOOL_STUDENTPUBLICATION:
2275
                $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref";
2276
                $data = $connection->fetchAssoc($sql);
2277
                if ($data) {
2278
                    $newId = $data['iid'];
2279
                }
2280
                break;
2281
            case TOOL_QUIZ:
2282
                $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref";
2283
                $data = $connection->fetchAssoc($sql);
2284
                if ($data) {
2285
                    $newId = $data['iid'];
2286
                }
2287
                break;
2288
            case TOOL_DOCUMENT:
2289
                $sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref";
2290
                $data = $connection->fetchAssoc($sql);
2291
                if ($data) {
2292
                    $newId = $data['iid'];
2293
                }
2294
                break;
2295
            case TOOL_FORUM:
2296
                $sql = "SELECT * FROM c_forum_forum WHERE c_id = $courseId AND forum_id = $ref";
2297
                $data = $connection->fetchAssoc($sql);
2298
                if ($data) {
2299
                    $newId = $data['iid'];
2300
                }
2301
                break;
2302
            case 'thread':
2303
                $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND thread_id = $ref";
2304
                $data = $connection->fetchAssoc($sql);
2305
                if ($data) {
2306
                    $newId = $data['iid'];
2307
                }
2308
                break;
2309
        }
2310
2311
        if (!empty($sql) && !empty($newId) && !empty($iid)) {
2312
            $sql = "UPDATE c_lp_item SET ref = $newId WHERE iid = $iid";
2313
            $connection->executeQuery($sql);
2314
        }
2315
    }
2316
2317
    // Set NULL if session = 0
2318
    $sql = "UPDATE c_item_property SET session_id = NULL WHERE session_id = 0";
2319
    $connection->executeQuery($sql);
2320
2321
    // Set NULL if group = 0
2322
    $sql = "UPDATE c_item_property SET to_group_id = NULL WHERE to_group_id = 0";
2323
    $connection->executeQuery($sql);
2324
2325
    // Set NULL if insert_user_id = 0
2326
    $sql = "UPDATE c_item_property SET insert_user_id = NULL WHERE insert_user_id = 0";
2327
    $connection->executeQuery($sql);
2328
2329
    // Delete session data of sessions that don't exist.
2330
    $sql = "DELETE FROM c_item_property
2331
            WHERE session_id IS NOT NULL AND session_id NOT IN (SELECT id FROM session)";
2332
    $connection->executeQuery($sql);
2333
2334
    // Delete group data of groups that don't exist.
2335
    $sql = "DELETE FROM c_item_property
2336
            WHERE to_group_id <> 0 AND to_group_id IS NOT NULL AND to_group_id NOT IN (SELECT DISTINCT iid FROM c_group_info)";
2337
    $connection->executeQuery($sql);
2338
    // This updates the group_id with c_group_info.iid instead of c_group_info.id
2339
2340
    if ($debug) {
2341
        error_log('update iids');
2342
    }
2343
2344
    $groupTableToFix = [
2345
        'c_group_rel_user',
2346
        'c_group_rel_tutor',
2347
        'c_permission_group',
2348
        'c_role_group',
2349
        'c_survey_invitation',
2350
        'c_attendance_calendar_rel_group',
2351
    ];
2352
2353
    foreach ($groupTableToFix as $table) {
2354
        $sql = "SELECT * FROM $table";
2355
        $result = $connection->fetchAll($sql);
2356
        foreach ($result as $item) {
2357
            $iid = $item['iid'];
2358
            $courseId = $item['c_id'];
2359
            $groupId = intval($item['group_id']);
2360
2361
            // Fix group id
2362
            if (!empty($groupId)) {
2363
                $sql = "SELECT * FROM c_group_info
2364
                        WHERE c_id = $courseId AND id = $groupId
2365
                        LIMIT 1";
2366
                $data = $connection->fetchAssoc($sql);
2367
                if (!empty($data)) {
2368
                    $newGroupId = $data['iid'];
2369
                    $sql = "UPDATE $table SET group_id = $newGroupId
2370
                            WHERE iid = $iid";
2371
                    $connection->executeQuery($sql);
2372
                } else {
2373
                    // The group does not exists clean this record
2374
                    $sql = "DELETE FROM $table WHERE iid = $iid";
2375
                    $connection->executeQuery($sql);
2376
                }
2377
            }
2378
        }
2379
    }
2380
2381
    // Fix c_item_property
2382
    if ($debug) {
2383
        error_log('update c_item_property');
2384
    }
2385
2386
    $sql = "SELECT * FROM course";
2387
    $courseList = $connection->fetchAll($sql);
2388
    if ($debug) {
2389
        error_log('Getting course list');
2390
    }
2391
2392
    $totalCourse = count($courseList);
2393
    $counter = 0;
2394
2395
    foreach ($courseList as $courseData) {
2396
        $courseId = $courseData['id'];
2397
        if ($debug) {
2398
            error_log('Updating course: '.$courseData['code']);
2399
        }
2400
2401
        $sql = "SELECT * FROM c_item_property WHERE c_id = $courseId";
2402
        $result = $connection->fetchAll($sql);
2403
        foreach ($result as $item) {
2404
            $sessionId = intval($item['session_id']);
2405
            $groupId = intval($item['to_group_id']);
2406
            $iid = $item['iid'];
2407
            $ref = $item['ref'];
2408
2409
            // Fix group id
2410
            // Commented group id is already fixed in Version20150603181728.php
2411
            /*if (!empty($groupId)) {
2412
                $sql = "SELECT * FROM c_group_info
2413
                        WHERE c_id = $courseId AND id = $groupId";
2414
                $data = $connection->fetchAssoc($sql);
2415
                if (!empty($data)) {
2416
                    $newGroupId = $data['iid'];
2417
                    $sql = "UPDATE c_item_property SET to_group_id = $newGroupId
2418
                            WHERE iid = $iid";
2419
                    $connection->executeQuery($sql);
2420
                } else {
2421
                    // The group does not exists clean this record
2422
                    $sql = "DELETE FROM c_item_property WHERE iid = $iid";
2423
                    $connection->executeQuery($sql);
2424
                }
2425
            }*/
2426
2427
            $sql = '';
2428
            $newId = '';
2429
            switch ($item['tool']) {
2430
                case TOOL_LINK:
2431
                    $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref ";
2432
                    break;
2433
                case TOOL_STUDENTPUBLICATION:
2434
                    $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref";
2435
                    break;
2436
                case TOOL_QUIZ:
2437
                    $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref";
2438
                    break;
2439
                case TOOL_DOCUMENT:
2440
                    $sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref";
2441
                    break;
2442
                case TOOL_FORUM:
2443
                    $sql = "SELECT * FROM c_forum_forum WHERE c_id = $courseId AND id = $ref";
2444
                    break;
2445
                case 'thread':
2446
                    $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND id = $ref";
2447
                    break;
2448
            }
2449
2450
            if (!empty($sql) && !empty($newId)) {
2451
                $data = $connection->fetchAssoc($sql);
2452
                if (isset($data['iid'])) {
2453
                    $newId = $data['iid'];
2454
                }
2455
                $sql = "UPDATE c_item_property SET ref = $newId WHERE iid = $iid";
2456
                error_log($sql);
2457
                $connection->executeQuery($sql);
2458
            }
2459
        }
2460
2461
        if ($debug) {
2462
            // Print a status in the log once in a while
2463
            error_log("Course process #$counter/$totalCourse");
2464
        }
2465
        $counter++;
2466
    }
2467
2468
    if ($debug) {
2469
        error_log('update gradebook_link');
2470
    }
2471
2472
    // Fix gradebook_link
2473
    $sql = "SELECT * FROM gradebook_link";
2474
    $result = $connection->fetchAll($sql);
2475
    foreach ($result as $item) {
2476
        $courseCode = $item['course_code'];
2477
        $categoryId = (int) $item['category_id'];
2478
2479
        $sql = "SELECT * FROM course WHERE code = '$courseCode'";
2480
        $courseInfo = $connection->fetchAssoc($sql);
2481
        if (empty($courseInfo)) {
2482
            continue;
2483
        }
2484
2485
        $courseId = $courseInfo['id'];
2486
2487
        $ref = $item['ref_id'];
2488
        $iid = $item['id'];
2489
2490
        $sql = '';
2491
        switch ($item['type']) {
2492
            case LINK_LEARNPATH:
2493
                $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref ";
2494
                break;
2495
            case LINK_STUDENTPUBLICATION:
2496
                $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref";
2497
                break;
2498
            case LINK_EXERCISE:
2499
                $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref";
2500
                break;
2501
            case LINK_ATTENDANCE:
2502
                //$sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref";
2503
                break;
2504
            case LINK_FORUM_THREAD:
2505
                $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND thread_id = $ref";
2506
                break;
2507
        }
2508
2509
        if (!empty($sql)) {
2510
            $data = $connection->fetchAssoc($sql);
2511
            if (isset($data) && isset($data['iid'])) {
2512
                $newId = $data['iid'];
2513
                $sql = "UPDATE gradebook_link SET ref_id = $newId
2514
                        WHERE id = $iid AND course_code = '$courseCode' AND category_id = $categoryId ";
2515
                $connection->executeQuery($sql);
2516
            }
2517
        }
2518
    }
2519
2520
    if ($debug) {
2521
        error_log('update groups');
2522
    }
2523
2524
    $sql = "SELECT * FROM groups";
2525
    $result = $connection->executeQuery($sql);
2526
    $groups = $result->fetchAll();
2527
    $oldGroups = [];
2528
    if (!empty($groups)) {
2529
        foreach ($groups as $group) {
2530
            if (empty($group['name'])) {
2531
                continue;
2532
            }
2533
2534
            $params = [
2535
                'name' => $group['name'],
2536
                'description' => $group['description'],
2537
                'group_type' => 1,
2538
                'picture' => $group['picture_uri'],
2539
                'url' => $group['url'],
2540
                'visibility' => $group['visibility'],
2541
                'updated_at' => $group['updated_on'],
2542
                'created_at' => $group['created_on'],
2543
            ];
2544
            $connection->insert('usergroup', $params);
2545
            $id = $connection->lastInsertId('id');
2546
            $oldGroups[$group['id']] = $id;
2547
        }
2548
    }
2549
2550
    if (!empty($oldGroups)) {
2551
        error_log('Moving group files');
2552
        foreach ($oldGroups as $oldId => $newId) {
2553
            $path = get_group_picture_path_by_id(
2554
                $oldId,
2555
                'system'
2556
            );
2557
2558
            if (!empty($path)) {
2559
                $newPath = str_replace(
2560
                    "groups/$oldId/",
2561
                    "groups/$newId/",
2562
                    $path['dir']
2563
                );
2564
                $command = "mv {$path['dir']} $newPath ";
2565
                error_log("Executing $command");
2566
                system($command);
2567
            }
2568
        }
2569
2570
        $sql = "SELECT * FROM group_rel_user";
2571
        $result = $connection->executeQuery($sql);
2572
        $dataList = $result->fetchAll();
2573
2574
        if (!empty($dataList)) {
2575
            foreach ($dataList as $data) {
2576
                if (isset($oldGroups[$data['group_id']])) {
2577
                    $data['group_id'] = $oldGroups[$data['group_id']];
2578
                    $userId = $data['user_id'];
2579
2580
                    $sql = "SELECT id FROM user WHERE user_id = $userId";
2581
                    $userResult = $connection->executeQuery($sql);
2582
                    $userInfo = $userResult->fetch();
2583
                    if (empty($userInfo)) {
2584
                        continue;
2585
                    }
2586
2587
                    $sql = "INSERT INTO usergroup_rel_user (usergroup_id, user_id, relation_type)
2588
                            VALUES ('{$data['group_id']}', '{$userId}', '{$data['relation_type']}')";
2589
                    $connection->executeQuery($sql);
2590
                }
2591
            }
2592
        }
2593
2594
        $sql = "SELECT * FROM group_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']]) && isset($oldGroups[$data['subgroup_id']])) {
2601
                    $data['group_id'] = $oldGroups[$data['group_id']];
2602
                    $data['subgroup_id'] = $oldGroups[$data['subgroup_id']];
2603
                    $sql = "INSERT INTO usergroup_rel_usergroup (group_id, subgroup_id, relation_type)
2604
                            VALUES ('{$data['group_id']}', '{$data['subgroup_id']}', '{$data['relation_type']}')";
2605
                    $connection->executeQuery($sql);
2606
                }
2607
            }
2608
        }
2609
2610
        $sql = "SELECT * FROM announcement_rel_group";
2611
        $result = $connection->executeQuery($sql);
2612
        $dataList = $result->fetchAll();
2613
2614
        if (!empty($dataList)) {
2615
            foreach ($dataList as $data) {
2616
                if (isset($oldGroups[$data['group_id']])) {
2617
                    // Deleting relation
2618
                    $sql = "DELETE FROM announcement_rel_group WHERE group_id = {$data['group_id']}";
2619
                    $connection->executeQuery($sql);
2620
2621
                    // Add new relation
2622
                    $data['group_id'] = $oldGroups[$data['group_id']];
2623
                    $sql = "INSERT INTO announcement_rel_group(group_id, announcement_id)
2624
                            VALUES ('{$data['group_id']}', '{$data['announcement_id']}')";
2625
                    $connection->executeQuery($sql);
2626
                }
2627
            }
2628
        }
2629
2630
        $sql = "SELECT * FROM group_rel_tag";
2631
        $result = $connection->executeQuery($sql);
2632
        $dataList = $result->fetchAll();
2633
        if (!empty($dataList)) {
2634
            foreach ($dataList as $data) {
2635
                if (isset($oldGroups[$data['group_id']])) {
2636
                    $data['group_id'] = $oldGroups[$data['group_id']];
2637
                    $sql = "INSERT INTO usergroup_rel_tag (tag_id, usergroup_id)
2638
                            VALUES ('{$data['tag_id']}', '{$data['group_id']}')";
2639
                    $connection->executeQuery($sql);
2640
                }
2641
            }
2642
        }
2643
    }
2644
2645
    if ($debug) {
2646
        error_log('update extra fields');
2647
    }
2648
2649
    // Extra fields
2650
    $extraFieldTables = [
2651
        ExtraField::USER_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_USER_FIELD),
2652
        ExtraField::COURSE_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_COURSE_FIELD),
2653
        //ExtraField::LP_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_LP_FIELD),
2654
        ExtraField::SESSION_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_SESSION_FIELD),
2655
        //ExtraField::CALENDAR_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_FIELD),
2656
        //ExtraField::QUESTION_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_FIELD),
2657
        //ExtraField::USER_FIELD_TYPE => //Database::get_main_table(TABLE_MAIN_SPECIFIC_FIELD),
2658
    ];
2659
2660
    foreach ($extraFieldTables as $type => $table) {
2661
        $sql = "SELECT * FROM $table ";
2662
        if ($debug) {
2663
            error_log($sql);
2664
        }
2665
        $result = $connection->query($sql);
2666
        $fields = $result->fetchAll();
2667
2668
        foreach ($fields as $field) {
2669
            if ($debug) {
2670
                error_log("Loading field: ".$field['field_variable']);
2671
            }
2672
            $originalId = $field['id'];
2673
2674
            $params = [
2675
                'extra_field_type' => $type,
2676
                'variable' => $field['field_variable'],
2677
                'field_type' => $field['field_type'],
2678
                'display_text' => $field['field_display_text'],
2679
                'default_value' => $field['field_default_value'],
2680
                'field_order' => $field['field_order'],
2681
                'visible' => $field['field_visible'],
2682
                'changeable' => $field['field_changeable'],
2683
                'filter' => $field['field_filter'],
2684
            ];
2685
2686
            $connection->insert('extra_field', $params);
2687
            $newExtraFieldId = $connection->lastInsertId();
2688
2689
            $values = [];
2690
            $handlerId = null;
2691
            switch ($type) {
2692
                case ExtraField::USER_FIELD_TYPE:
2693
                    $optionTable = Database::get_main_table(
2694
                        TABLE_MAIN_USER_FIELD_OPTIONS
2695
                    );
2696
                    $valueTable = Database::get_main_table(
2697
                        TABLE_MAIN_USER_FIELD_VALUES
2698
                    );
2699
                    $handlerId = 'user_id';
2700
                    break;
2701
                case ExtraField::COURSE_FIELD_TYPE:
2702
                    $optionTable = Database::get_main_table(
2703
                        TABLE_MAIN_COURSE_FIELD_OPTIONS
2704
                    );
2705
                    $valueTable = Database::get_main_table(
2706
                        TABLE_MAIN_COURSE_FIELD_VALUES
2707
                    );
2708
                    $handlerId = 'c_id';
2709
                    break;
2710
                case ExtraField::SESSION_FIELD_TYPE:
2711
                    $optionTable = Database::get_main_table(
2712
                        TABLE_MAIN_SESSION_FIELD_OPTIONS
2713
                    );
2714
                    $valueTable = Database::get_main_table(
2715
                        TABLE_MAIN_SESSION_FIELD_VALUES
2716
                    );
2717
                    $handlerId = 'session_id';
2718
                    break;
2719
            }
2720
2721
            if (!empty($optionTable)) {
2722
                $sql = "SELECT * FROM $optionTable WHERE field_id = $originalId ";
2723
                $result = $connection->query($sql);
2724
                $options = $result->fetchAll();
2725
2726
                foreach ($options as $option) {
2727
                    $params = [
2728
                        'display_text' => $option['option_display_text'],
2729
                        'field_id' => $newExtraFieldId,
2730
                        'option_order' => $option['option_order'],
2731
                        'option_value' => $option['option_value'],
2732
                    ];
2733
                    $connection->insert('extra_field_options', $params);
2734
                }
2735
2736
                $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...
2737
                $result = $connection->query($sql);
2738
                $values = $result->fetchAll();
2739
                if ($debug) {
2740
                    error_log("Fetch all values for field");
2741
                }
2742
            }
2743
2744
            if (!empty($values)) {
2745
                if ($debug) {
2746
                    error_log("Saving field value in new table");
2747
                }
2748
                $k = 0;
2749
                foreach ($values as $value) {
2750
                    if (isset($value[$handlerId])) {
2751
                        // Insert without the use of the entity as it reduces
2752
                        // speed to 2 records per second (much too slow)
2753
                        $params = [
2754
                            'field_id' => $newExtraFieldId,
2755
                            'value' => $value['field_value'],
2756
                            'item_id' => $value[$handlerId],
2757
                        ];
2758
                        $connection->insert('extra_field_values', $params);
2759
                        if ($debug && ($k % 10000 == 0)) {
2760
                            error_log("Saving field $k");
2761
                        }
2762
                        $k++;
2763
                    }
2764
                }
2765
            }
2766
        }
2767
    }
2768
2769
    if ($debug) {
0 ignored issues
show
introduced by
$debug is of type mixed, thus it always evaluated to true.
Loading history...
2770
        error_log('Remove index');
2771
    }
2772
2773
    // Drop temporary indexes added to increase speed of this function's queries
2774
    $sql = "ALTER TABLE c_document DROP INDEX tmpidx_doc";
2775
    $connection->executeQuery($sql);
2776
    $sql = "ALTER TABLE c_student_publication DROP INDEX tmpidx_stud";
2777
    $connection->executeQuery($sql);
2778
    $sql = "ALTER TABLE c_quiz DROP INDEX tmpidx_quiz";
2779
    $connection->executeQuery($sql);
2780
    $sql = "ALTER TABLE c_item_property DROP INDEX tmpidx_ip";
2781
    $connection->executeQuery($sql);
2782
2783
    if ($debug) {
2784
        error_log('Finish fixId function');
2785
    }
2786
2787
    fixLpId($connection, true);
2788
}
2789
2790
/**
2791
 * @param \Doctrine\DBAL\Connection $connection
2792
 * @param $debug
2793
 *
2794
 * @throws \Doctrine\DBAL\DBALException
2795
 */
2796
function fixLpId($connection, $debug)
2797
{
2798
    if ($debug) {
2799
        error_log('Fix lp.id lp.iids');
2800
    }
2801
2802
    $sql = 'SELECT id, title, code FROM course';
2803
    $result = $connection->query($sql);
2804
    $courses = $result->fetchAll();
2805
2806
    $sql = 'SELECT id FROM session';
2807
    $result = $connection->query($sql);
2808
    $sessions = $result->fetchAll();
2809
2810
    $tblCLp = Database::get_course_table(TABLE_LP_MAIN);
2811
    $tblCLpItem = Database::get_course_table(TABLE_LP_ITEM);
2812
    $toolTable = Database::get_course_table(TABLE_TOOL_LIST);
2813
2814
    if (!empty($sessions)) {
2815
        $sessions = array_column($sessions, 'id');
2816
        $sessions[] = 0;
2817
    } else {
2818
        $sessions = [0];
2819
    }
2820
2821
    foreach ($courses as $course) {
2822
        $courseId = $course['id'];
2823
        $sql = "SELECT * FROM $tblCLp WHERE c_id = $courseId AND iid <> id ORDER by iid";
2824
        $result = $connection->query($sql);
2825
        if ($debug) {
2826
            error_log('-------------');
2827
            error_log("Entering Lps in course #$courseId");
2828
            error_log($sql);
2829
        }
2830
        $lpList = $result->fetchAll();
2831
        $myOnlyLpList = [];
2832
        if (!empty($lpList)) {
2833
            foreach ($lpList as $lpInfo) {
2834
                $oldId = $lpInfo['id'];
2835
                $sql = "SELECT * FROM $tblCLpItem WHERE c_id = $courseId AND lp_id = $oldId ORDER by iid";
2836
                $result = $connection->query($sql);
2837
                $items = $result->fetchAll();
2838
                $lpInfo['lp_list'] = $items;
2839
                $myOnlyLpList[] = $lpInfo;
2840
            }
2841
        }
2842
2843
        if (!empty($myOnlyLpList)) {
2844
            foreach ($myOnlyLpList as $lpInfo) {
2845
                $lpIid = $lpInfo['iid'];
2846
                $oldId = $lpInfo['id'];
2847
                $items = $lpInfo['lp_list'];
2848
2849
                if (empty($items)) {
2850
                    continue;
2851
                }
2852
                $itemList = [];
2853
                foreach ($items as $subItem) {
2854
                    $itemList[$subItem['id']] = $subItem['iid'];
2855
                }
2856
                $variablesToFix = [
2857
                    'parent_item_id',
2858
                    'next_item_id',
2859
                    'prerequisite',
2860
                    'previous_item_id',
2861
                ];
2862
2863
                foreach ($sessions as $sessionId) {
2864
                    $correctLink = "lp/lp_controller.php?action=view&lp_id=$lpIid&id_session=$sessionId";
2865
                    $link = "newscorm/lp_controller.php?action=view&lp_id=$oldId&id_session=$sessionId";
2866
                    $secondLink = "lp/lp_controller.php?action=view&lp_id=$oldId&id_session=$sessionId";
2867
                    $sql = "UPDATE $toolTable 
2868
                        SET link = '$correctLink'
2869
                        WHERE c_id = $courseId AND (link = '$link' OR link ='$secondLink')";
2870
                    $connection->query($sql);
2871
                    if ($debug) {
2872
                        //error_log("Fix wrong c_tool links");
2873
                        //error_log($sql);
2874
                    }
2875
                }
2876
2877
                foreach ($items as $item) {
2878
                    $itemIid = $item['iid'];
2879
                    $itemId = $item['id'];
2880
                    foreach ($variablesToFix as $variable) {
2881
                        if (!empty($item[$variable]) && isset($itemList[$item[$variable]])) {
2882
                            $newId = $itemList[$item[$variable]];
2883
                            $sql = "UPDATE $tblCLpItem SET $variable = $newId 
2884
                                    WHERE iid = $itemIid AND c_id = $courseId AND lp_id = $oldId";
2885
                            $connection->query($sql);
2886
                            if ($debug) {
2887
                                //error_log($sql);
2888
                            }
2889
                        }
2890
                    }
2891
2892
                    if ($item['item_type'] == 'document' && !empty($item['path'])) {
2893
                        $oldDocumentId = $item['path'];
2894
                        $sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $oldDocumentId";
2895
                        $result = $connection->query($sql);
2896
                        $document = $result->fetch();
2897
                        if (!empty($document)) {
2898
                            $newDocumentId = $document['iid'];
2899
                            if (!empty($newDocumentId)) {
2900
                                $sql = "UPDATE $tblCLpItem SET path = $newDocumentId 
2901
                                    WHERE iid = $itemIid AND c_id = $courseId";
2902
                                $connection->query($sql);
2903
                                if ($debug) {
2904
                                    //error_log("Fix document: ");
2905
                                    //error_log($sql);
2906
                                }
2907
                            }
2908
                        }
2909
                    }
2910
2911
                    // c_lp_view
2912
                    $sql = "UPDATE c_lp_view SET last_item = $itemIid 
2913
                            WHERE c_id = $courseId AND last_item = $itemId AND lp_id = $oldId";
2914
                    $connection->query($sql);
2915
2916
                    // c_lp_item_view
2917
                    $sql = "UPDATE c_lp_item_view SET lp_item_id = $itemIid 
2918
                            WHERE c_id = $courseId AND lp_item_id = $itemId";
2919
                    $connection->query($sql);
2920
2921
                    // Update track_exercises
2922
                    $sql = "UPDATE track_e_exercises SET orig_lp_item_id = $itemIid 
2923
                            WHERE c_id = $courseId AND orig_lp_id = $oldId AND orig_lp_item_id = $itemId";
2924
                    $connection->query($sql);
2925
2926
                    // c_forum_thread
2927
                    $sql = "UPDATE c_forum_thread SET lp_item_id = $itemIid 
2928
                            WHERE c_id = $courseId AND lp_item_id = $itemId";
2929
                    $connection->query($sql);
2930
2931
                    // orig_lp_item_view_id
2932
                    $sql = "SELECT * FROM c_lp_view
2933
                            WHERE c_id = $courseId AND lp_id = $oldId";
2934
                    $result = $connection->query($sql);
2935
                    $itemViewList = $result->fetchAll();
2936
                    if ($itemViewList) {
2937
                        foreach ($itemViewList as $itemView) {
2938
                            $userId = $itemView['user_id'];
2939
                            $oldItemViewId = $itemView['id'];
2940
                            $newItemView = $itemView['iid'];
2941
2942
                            if (empty($oldItemViewId)) {
2943
                                continue;
2944
                            }
2945
2946
                            $sql = "UPDATE track_e_exercises 
2947
                                SET orig_lp_item_view_id = $newItemView 
2948
                                WHERE 
2949
                                  c_id = $courseId AND 
2950
                                  orig_lp_id = $oldId AND 
2951
                                  orig_lp_item_id = $itemIid AND 
2952
                                  orig_lp_item_view_id = $oldItemViewId AND 
2953
                                  exe_user_id = $userId                                       
2954
                                  ";
2955
                            $connection->query($sql);
2956
2957
                            /*$sql = "UPDATE c_lp_item_view
2958
                                    SET lp_view_id = $newItemView
2959
                                    WHERE
2960
                                      lp_view_id = $oldItemViewId AND
2961
                                      c_id = $courseId
2962
                                  ";
2963
                            $connection->query($sql);*/
2964
                        }
2965
                    }
2966
2967
                    $sql = "UPDATE $tblCLpItem SET lp_id = $lpIid 
2968
                            WHERE c_id = $courseId AND lp_id = $oldId AND id = $itemId";
2969
                    $connection->query($sql);
2970
2971
                    $sql = "UPDATE $tblCLpItem SET id = iid 
2972
                            WHERE c_id = $courseId AND lp_id = $oldId AND id = $itemId";
2973
                    $connection->query($sql);
2974
                }
2975
2976
                $sql = "UPDATE c_lp_view SET lp_id = $lpIid WHERE c_id = $courseId AND lp_id = $oldId";
2977
                $connection->query($sql);
2978
2979
                $sql = "UPDATE c_forum_forum SET lp_id = $lpIid WHERE c_id = $courseId AND lp_id = $oldId";
2980
                $connection->query($sql);
2981
2982
                // Update track_exercises.
2983
                $sql = "UPDATE track_e_exercises SET orig_lp_id = $lpIid 
2984
                        WHERE c_id = $courseId AND orig_lp_id = $oldId";
2985
                $connection->query($sql);
2986
2987
                $sql = "UPDATE $tblCLp SET id = iid WHERE c_id = $courseId AND id = $oldId ";
2988
                $connection->query($sql);
2989
            }
2990
        }
2991
    }
2992
2993
    if ($debug) {
2994
        error_log('END Fix lp.id lp.iids');
2995
    }
2996
}
2997
2998
/**
2999
 * @param string $distFile
3000
 * @param string $envFile
3001
 * @param array  $params
3002
 */
3003
function updateEnvFile($distFile, $envFile, $params)
3004
{
3005
    $contents = file_get_contents($distFile);
3006
    $contents = str_replace(array_keys($params), array_values($params), $contents);
3007
    file_put_contents($envFile, $contents);
3008
}
3009
3010
/**
3011
 * @param SymfonyContainer $container
3012
 * @param EntityManager    $manager
3013
 */
3014
function installGroups($container, $manager)
3015
{
3016
    // Creating fos_group (groups and roles)
3017
    $groupManager = $container->get('fos_user.group_manager');
3018
    $groups = [
3019
        [
3020
            'code' => 'ADMIN',
3021
            'title' => 'Administrators',
3022
            'roles' => ['ROLE_ADMIN'],
3023
        ],
3024
        [
3025
            'code' => 'STUDENT',
3026
            'title' => 'Students',
3027
            'roles' => ['ROLE_STUDENT'],
3028
        ],
3029
        [
3030
            'code' => 'TEACHER',
3031
            'title' => 'Teachers',
3032
            'roles' => ['ROLE_TEACHER'],
3033
        ],
3034
        [
3035
            'code' => 'RRHH',
3036
            'title' => 'Human resources manager',
3037
            'roles' => ['ROLE_RRHH'],
3038
        ],
3039
        [
3040
            'code' => 'SESSION_MANAGER',
3041
            'title' => 'Session',
3042
            'roles' => ['ROLE_SESSION_MANAGER'],
3043
        ],
3044
        [
3045
            'code' => 'QUESTION_MANAGER',
3046
            'title' => 'Question manager',
3047
            'roles' => ['ROLE_QUESTION_MANAGER'],
3048
        ],
3049
        [
3050
            'code' => 'STUDENT_BOSS',
3051
            'title' => 'Student boss',
3052
            'roles' => ['ROLE_STUDENT_BOSS'],
3053
        ],
3054
        [
3055
            'code' => 'INVITEE',
3056
            'title' => 'Invitee',
3057
            'roles' => ['ROLE_INVITEE'],
3058
        ],
3059
    ];
3060
3061
    foreach ($groups as $groupData) {
3062
        $criteria = ['code' => $groupData['code']];
3063
        $groupExists = $groupManager->findGroupBy($criteria);
3064
        if (!$groupExists) {
3065
            $group = $groupManager->createGroup($groupData['title']);
3066
            $group->setCode($groupData['code']);
3067
            foreach ($groupData['roles'] as $role) {
3068
                $group->addRole($role);
3069
            }
3070
            $manager->persist($group);
3071
            $groupManager->updateGroup($group, true);
3072
        }
3073
    }
3074
}
3075
3076
/**
3077
 * @param SymfonyContainer $container
3078
 */
3079
function installPages($container)
3080
{
3081
    $siteManager = Container::getSiteManager();
3082
3083
    // Create site
3084
    /** @var Chamilo\PageBundle\Entity\Site $site */
3085
    $site = $siteManager->create();
3086
    $site->setHost('localhost');
3087
    $site->setEnabled(true);
3088
    $site->setName('localhost');
3089
    $site->setEnabledFrom(new \DateTime('now'));
3090
    $site->setEnabledTo(new \DateTime('+20 years'));
3091
    $site->setRelativePath('');
3092
    $site->setIsDefault(true);
3093
    $site->setLocale('en');
3094
    $siteManager->save($site);
3095
3096
    // Create home page
3097
    /** @var PageManager $pageManager */
3098
    $pageManager = $container->get('sonata.page.manager.page');
3099
    /** @var \Sonata\PageBundle\Model\Page $page */
3100
    $page = $pageManager->create();
3101
    $page->setSlug('homepage');
3102
    $page->setUrl('/');
3103
    $page->setName('homepage');
3104
    $page->setTitle('home');
3105
    $page->setEnabled(true);
3106
    $page->setDecorate(1);
3107
    $page->setRequestMethod('GET|POST|HEAD|DELETE|PUT');
3108
    $page->setTemplateCode('default');
3109
    $page->setRouteName('homepage');
3110
    //$page->setParent($this->getReference('page-homepage'));
3111
    $page->setSite($site);
3112
    $pageManager->save($page);
3113
3114
    // Create welcome page
3115
    $pageWelcome = $pageManager->create();
3116
    $pageWelcome->setSlug('welcome');
3117
    $pageWelcome->setUrl('/welcome');
3118
    $pageWelcome->setName('welcome');
3119
    $pageWelcome->setTitle('welcome');
3120
    $pageWelcome->setEnabled(true);
3121
    $pageWelcome->setDecorate(1);
3122
    $pageWelcome->setRequestMethod('GET');
3123
    $pageWelcome->setTemplateCode('default');
3124
    $pageWelcome->setRouteName('welcome');
3125
    $pageWelcome->setParent($page);
3126
    $pageWelcome->setSite($site);
3127
    $pageManager->save($pageWelcome);
3128
3129
    // Creating page blocks
3130
    $templateManager = $container->get('sonata.page.template_manager');
3131
    $template = $templateManager->get('default');
3132
    $templateContainers = $template->getContainers();
3133
3134
    $containers = [];
3135
    foreach ($templateContainers as $id => $area) {
3136
        $containers[$id] = [
3137
            'area' => $area,
3138
            'block' => false,
3139
        ];
3140
    }
3141
3142
    // Create blocks for this page
3143
    $blockInteractor = $container->get('sonata.page.block_interactor');
3144
    $parentBlock = null;
3145
    foreach ($containers as $id => $area) {
3146
        if (false === $area['block'] && $templateContainers[$id]['shared'] === false) {
3147
            $block = $blockInteractor->createNewContainer(
3148
                [
3149
                    'page' => $pageWelcome,
3150
                    'name' => $templateContainers[$id]['name'],
3151
                    'code' => $id,
3152
                ]
3153
            );
3154
3155
            if ($id === 'content' && $templateContainers[$id]['name'] == 'Main content') {
3156
                $parentBlock = $block;
3157
            }
3158
        }
3159
    }
3160
3161
    // Create block in main content
3162
    $block = $container->get('sonata.page.manager.block');
3163
    /** @var \Sonata\BlockBundle\Model\Block $myBlock */
3164
    $myBlock = $block->create();
3165
    $myBlock->setType('sonata.formatter.block.formatter');
3166
    $myBlock->setSetting('format', 'richhtml');
3167
    $myBlock->setSetting('content', '');
3168
    $myBlock->setSetting('rawContent', '');
3169
    $myBlock->setSetting('template', '@SonataFormatter/Block/block_formatter.html.twig');
3170
    $myBlock->setParent($parentBlock);
3171
    $pageWelcome->addBlocks($myBlock);
3172
    $pageManager->save($pageWelcome);
3173
}
3174
3175
/**
3176
 * @param SymfonyContainer $container
3177
 * @param EntityManager    $manager
3178
 * @param bool             $upgrade
3179
 */
3180
function installSchemas($container, $manager, $upgrade = false)
3181
{
3182
    $settingsManager = Container::getSettingsManager();
3183
3184
    $accessUrl = $manager->getRepository('ChamiloCoreBundle:AccessUrl')->find(1);
3185
    if (!$accessUrl) {
3186
        // Creating AccessUrl
3187
        $accessUrl = new AccessUrl();
3188
        $accessUrl
3189
            ->setUrl('http://localhost/')
3190
            ->setDescription('')
3191
            ->setActive(1)
3192
        ;
3193
        $manager->persist($accessUrl);
3194
        $manager->flush();
3195
    }
3196
3197
    // Install course tools (table "tool")
3198
    $toolChain = $container->get('chamilo_course.tool_chain');
3199
    $toolChain->createTools($manager);
3200
3201
    if ($upgrade) {
3202
        $settingsManager->updateSchemas($accessUrl);
3203
    } else {
3204
        // Installing schemas (filling settings_current table)
3205
        $settingsManager->installSchemas($accessUrl);
3206
    }
3207
}
3208
3209
/**
3210
 * @param SymfonyContainer $container
3211
 */
3212
function upgradeWithContainer($container)
3213
{
3214
    Container::setContainer($container);
3215
    Container::setLegacyServices($container, false);
3216
    error_log('setLegacyServices');
3217
    $manager = Database::getManager();
3218
    installGroups($container, $manager);
3219
    error_log('installGroups');
3220
    installSchemas($container, $manager, true);
3221
    error_log('installSchemas');
3222
    installPages($container);
3223
    error_log('installPages');
3224
}
3225
3226
/**
3227
 * After the schema was created (table creation), the function adds
3228
 * admin/platform information.
3229
 *
3230
 * @param \Psr\Container\ContainerInterface $container
3231
 * @param string                            $sysPath
3232
 * @param string                            $encryptPassForm
3233
 * @param string                            $passForm
3234
 * @param string                            $adminLastName
3235
 * @param string                            $adminFirstName
3236
 * @param string                            $loginForm
3237
 * @param string                            $emailForm
3238
 * @param string                            $adminPhoneForm
3239
 * @param string                            $languageForm
3240
 * @param string                            $institutionForm
3241
 * @param string                            $institutionUrlForm
3242
 * @param string                            $siteName
3243
 * @param string                            $allowSelfReg
3244
 * @param string                            $allowSelfRegProf
3245
 * @param string                            $installationProfile Installation profile, if any was provided
3246
 */
3247
function finishInstallationWithContainer(
3248
    $container,
3249
    $sysPath,
3250
    $encryptPassForm,
3251
    $passForm,
3252
    $adminLastName,
3253
    $adminFirstName,
3254
    $loginForm,
3255
    $emailForm,
3256
    $adminPhoneForm,
3257
    $languageForm,
3258
    $institutionForm,
3259
    $institutionUrlForm,
3260
    $siteName,
3261
    $allowSelfReg,
3262
    $allowSelfRegProf,
3263
    $installationProfile = ''
3264
) {
3265
    $sysPath = !empty($sysPath) ? $sysPath : api_get_path(SYS_PATH);
3266
    Container::setContainer($container);
3267
    Container::setLegacyServices($container, false);
3268
3269
    $manager = Database::getManager();
3270
    $connection = $manager->getConnection();
3271
    $sql = getVersionTable();
3272
    // Add version table
3273
    $connection->executeQuery($sql);
3274
3275
    // Add tickets defaults
3276
    $ticketProject = new TicketProject();
3277
    $ticketProject
3278
        ->setId(1)
3279
        ->setName('Ticket System')
3280
        ->setInsertUserId(1);
3281
3282
    $manager->persist($ticketProject);
3283
    $manager->flush();
3284
3285
    $categories = [
3286
        get_lang('TicketEnrollment') => get_lang('TicketsAboutEnrollment'),
3287
        get_lang('TicketGeneralInformation') => get_lang('TicketsAboutGeneralInformation'),
3288
        get_lang('TicketRequestAndPapework') => get_lang('TicketsAboutRequestAndPapework'),
3289
        get_lang('TicketAcademicIncidence') => get_lang('TicketsAboutAcademicIncidence'),
3290
        get_lang('TicketVirtualCampus') => get_lang('TicketsAboutVirtualCampus'),
3291
        get_lang('TicketOnlineEvaluation') => get_lang('TicketsAboutOnlineEvaluation'),
3292
    ];
3293
3294
    $i = 1;
3295
    foreach ($categories as $category => $description) {
3296
        // Online evaluation requires a course
3297
        $ticketCategory = new TicketCategory();
3298
        $ticketCategory
3299
            ->setId($i)
3300
            ->setName($category)
3301
            ->setDescription($description)
3302
            ->setProject($ticketProject)
3303
            ->setInsertUserId(1);
3304
3305
        $isRequired = $i == 6;
3306
        $ticketCategory->setCourseRequired($isRequired);
3307
3308
        $manager->persist($ticketCategory);
3309
        $manager->flush();
3310
3311
        $i++;
3312
    }
3313
3314
    // Default Priorities
3315
    $defaultPriorities = [
3316
        TicketManager::PRIORITY_NORMAL => get_lang('PriorityNormal'),
3317
        TicketManager::PRIORITY_HIGH => get_lang('PriorityHigh'),
3318
        TicketManager::PRIORITY_LOW => get_lang('PriorityLow'),
3319
    ];
3320
3321
    $i = 1;
3322
    foreach ($defaultPriorities as $code => $priority) {
3323
        $ticketPriority = new TicketPriority();
3324
        $ticketPriority
3325
            ->setId($i)
3326
            ->setName($priority)
3327
            ->setCode($code)
3328
            ->setInsertUserId(1);
3329
3330
        $manager->persist($ticketPriority);
3331
        $manager->flush();
3332
        $i++;
3333
    }
3334
3335
    $table = Database::get_main_table(TABLE_TICKET_STATUS);
3336
3337
    // Default status
3338
    $defaultStatus = [
3339
        TicketManager::STATUS_NEW => get_lang('StatusNew'),
3340
        TicketManager::STATUS_PENDING => get_lang('StatusPending'),
3341
        TicketManager::STATUS_UNCONFIRMED => get_lang('StatusUnconfirmed'),
3342
        TicketManager::STATUS_CLOSE => get_lang('StatusClose'),
3343
        TicketManager::STATUS_FORWARDED => get_lang('StatusForwarded'),
3344
    ];
3345
3346
    $i = 1;
3347
    foreach ($defaultStatus as $code => $status) {
3348
        $attributes = [
3349
            'id' => $i,
3350
            'code' => $code,
3351
            'name' => $status,
3352
        ];
3353
        Database::insert($table, $attributes);
3354
        $i++;
3355
    }
3356
3357
    installGroups($container, $manager);
3358
    installSchemas($container, $manager);
3359
    installPages($container);
3360
3361
    // Inserting default data
3362
    $data = file_get_contents($sysPath.'main/install/data.sql');
3363
    $result = $manager->getConnection()->prepare($data);
3364
    $result->execute();
3365
    $result->closeCursor();
3366
3367
    UserManager::setPasswordEncryption($encryptPassForm);
3368
3369
    // Create admin user.
3370
    @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

3370
    /** @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...
3371
        $adminFirstName,
3372
        $adminLastName,
3373
        1,
3374
        $emailForm,
3375
        $loginForm,
3376
        $passForm,
3377
        'ADMIN', //$official_code = '',
3378
        $languageForm,
3379
        $adminPhoneForm,
3380
        '', //$picture_uri = '',
3381
        PLATFORM_AUTH_SOURCE,
3382
        '', //$expirationDate,
3383
        1,
3384
        0,
3385
        null,
3386
        '',
3387
        false, //$send_mail = false,
3388
        true, //$isAdmin = false
3389
        '',
3390
        false,
3391
        '',
3392
        1
3393
    );
3394
3395
    // Create anonymous user.
3396
    @UserManager::create_user(
3397
        'Joe',
3398
        'Anonymous',
3399
        6,
3400
        'anonymous@localhost',
3401
        'anon',
3402
        'anon',
3403
        'anonymous', //$official_code = '',
3404
        $languageForm,
3405
        '',
3406
        '', //$picture_uri = '',
3407
        PLATFORM_AUTH_SOURCE,
3408
        '',
3409
        1,
3410
        0,
3411
        null,
3412
        '',
3413
        false, //$send_mail = false,
3414
        false, //$isAdmin = false
3415
        '',
3416
        false,
3417
        '',
3418
        1
3419
    );
3420
3421
    // Set default language
3422
    Database::update(
3423
        Database::get_main_table(TABLE_MAIN_LANGUAGE),
3424
        ['available' => 1],
3425
        ['dokeos_folder = ?' => $languageForm]
3426
    );
3427
3428
    // Install settings
3429
    installSettings(
3430
        $institutionForm,
3431
        $institutionUrlForm,
3432
        $siteName,
3433
        $emailForm,
3434
        $adminLastName,
3435
        $adminFirstName,
3436
        $languageForm,
3437
        $allowSelfReg,
3438
        $allowSelfRegProf,
3439
        $installationProfile
3440
    );
3441
3442
    lockSettings();
3443
    updateDirAndFilesPermissions();
3444
3445
    // Set the latest version
3446
    /*$path = $sysPath.'app/Migrations/Schema/V111/';
3447
    $finder = new \Symfony\Component\Finder\Finder();
3448
    $files = $finder->files()->in($path);
3449
3450
    // Needed for chash
3451
    createVersionTable();
3452
3453
    foreach ($files as $version) {
3454
        $version = str_replace(['Version', '.php'], '', $version->getFilename());
3455
        $sql = "INSERT INTO version (version) VALUES ('$version')";
3456
        Database::query($sql);
3457
    }*/
3458
}
3459
3460
/**
3461
 * Creates 'version' table.
3462
 */
3463
function createVersionTable()
3464
{
3465
    $sql = getVersionTable();
3466
    Database::query($sql);
3467
}
3468
3469
/**
3470
 * Get version creation table query.
3471
 *
3472
 * @return string
3473
 */
3474
function getVersionTable()
3475
{
3476
    return 'CREATE TABLE IF NOT EXISTS version (id int unsigned NOT NULL AUTO_INCREMENT, version varchar(20), PRIMARY KEY(id), UNIQUE(version));';
3477
}
3478
3479
/**
3480
 * Update settings based on installation profile defined in a JSON file.
3481
 *
3482
 * @param string $installationProfile The name of the JSON file in main/install/profiles/ folder
3483
 *
3484
 * @return bool false on failure (no bad consequences anyway, just ignoring profile)
3485
 */
3486
function installProfileSettings($installationProfile = '')
3487
{
3488
    if (empty($installationProfile)) {
3489
        return false;
3490
    }
3491
    $jsonPath = api_get_path(SYS_PATH).'main/install/profiles/'.$installationProfile.'.json';
3492
    // Make sure the path to the profile is not hacked
3493
    if (!Security::check_abs_path($jsonPath, api_get_path(SYS_PATH).'main/install/profiles/')) {
3494
        return false;
3495
    }
3496
    if (!is_file($jsonPath)) {
3497
        return false;
3498
    }
3499
    if (!is_readable($jsonPath)) {
3500
        return false;
3501
    }
3502
    if (!function_exists('json_decode')) {
3503
        // The php-json extension is not available. Ignore profile.
3504
        return false;
3505
    }
3506
    $json = file_get_contents($jsonPath);
3507
    $params = json_decode($json);
3508
    if ($params === false or $params === null) {
3509
        return false;
3510
    }
3511
    $settings = $params->params;
3512
    if (!empty($params->parent)) {
3513
        installProfileSettings($params->parent);
3514
    }
3515
3516
    $tblSettings = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
3517
3518
    foreach ($settings as $id => $param) {
3519
        $conditions = ['variable = ? ' => $param->variable];
3520
3521
        if (!empty($param->subkey)) {
3522
            $conditions['AND subkey = ? '] = $param->subkey;
3523
        }
3524
3525
        Database::update(
3526
            $tblSettings,
3527
            ['selected_value' => $param->selected_value],
3528
            $conditions
3529
        );
3530
    }
3531
3532
    return true;
3533
}
3534
3535
/**
3536
 * Quick function to remove a directory with its subdirectories.
3537
 *
3538
 * @param $dir
3539
 */
3540
function rrmdir($dir)
3541
{
3542
    if (is_dir($dir)) {
3543
        $objects = scandir($dir);
3544
        foreach ($objects as $object) {
3545
            if ($object != "." && $object != "..") {
3546
                if (filetype($dir."/".$object) == "dir") {
3547
                    @rrmdir($dir."/".$object);
0 ignored issues
show
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...
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

3547
                    /** @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...
3548
                } else {
3549
                    @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

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