Completed
Push — master ( d0dde4...04c511 )
by Julito
15:02
created

finishInstallationWithContainer()   F

Complexity

Conditions 11

Size

Total Lines 298
Code Lines 196

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 11
eloc 196
nop 16
dl 0
loc 298
rs 3.1764
c 3
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

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

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

Commonly applied refactorings include:

Many Parameters

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

There are several approaches to avoid long parameter lists:

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

120
    /** @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...
121
) {
122
    $currentPhpValue = getPhpSetting($phpSetting);
123
    if ($currentPhpValue == $recommendedValue) {
124
        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

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

353
    $buffer = fread(/** @scrutinizer ignore-type */ $fp, filesize($filename));
Loading history...
354
    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

354
    fclose(/** @scrutinizer ignore-type */ $fp);
Loading history...
355
356
    return explode('<br />', nl2br($buffer));
357
}
358
359
/**
360
 * We assume this function is called from install scripts that reside inside the install folder.
361
 */
362
function set_file_folder_permissions()
363
{
364
    @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

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

938
    /** @scrutinizer ignore-unhandled */ @unlink($course_dir.'/test.php');

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...
939
    @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

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

1082
            @chmod($checked_writable, /** @scrutinizer ignore-type */ $perm);
Loading history...
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

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

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

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

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

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

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

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

2058
            /** @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...
2059
        }
2060
    }
2061
2062
    return $output;
2063
}
2064
2065
/**
2066
 * Save settings values.
2067
 *
2068
 * @param string $organizationName
2069
 * @param string $organizationUrl
2070
 * @param string $siteName
2071
 * @param string $adminEmail
2072
 * @param string $adminLastName
2073
 * @param string $adminFirstName
2074
 * @param string $language
2075
 * @param string $allowRegistration
2076
 * @param string $allowTeacherSelfRegistration
2077
 * @param string $installationProfile          The name of an installation profile file in main/install/profiles/
2078
 */
2079
function installSettings(
2080
    $organizationName,
2081
    $organizationUrl,
2082
    $siteName,
2083
    $adminEmail,
2084
    $adminLastName,
2085
    $adminFirstName,
2086
    $language,
2087
    $allowRegistration,
2088
    $allowTeacherSelfRegistration,
2089
    $installationProfile = ''
2090
) {
2091
    $allowTeacherSelfRegistration = $allowTeacherSelfRegistration ? 'true' : 'false';
2092
2093
    $settings = [
2094
        'institution' => $organizationName,
2095
        'institution_url' => $organizationUrl,
2096
        'site_name' => $siteName,
2097
        'administrator_email' => $adminEmail,
2098
        'administrator_surname' => $adminLastName,
2099
        'administrator_name' => $adminFirstName,
2100
        'platform_language' => $language,
2101
        'allow_registration' => $allowRegistration,
2102
        'allow_registration_as_teacher' => $allowTeacherSelfRegistration,
2103
    ];
2104
2105
    foreach ($settings as $variable => $value) {
2106
        $sql = "UPDATE settings_current
2107
                SET selected_value = '$value'
2108
                WHERE variable = '$variable'";
2109
        Database::query($sql);
2110
    }
2111
    installProfileSettings($installationProfile);
2112
}
2113
2114
/**
2115
 * Executes DB changes based in the classes defined in
2116
 * src/Chamilo/CoreBundle/Migrations/Schema/*.
2117
 *
2118
 * @param string        $chamiloVersion
2119
 * @param EntityManager $manager
2120
 *
2121
 * @throws \Doctrine\DBAL\DBALException
2122
 *
2123
 * @return bool
2124
 */
2125
function migrate($chamiloVersion, EntityManager $manager)
2126
{
2127
    $debug = true;
2128
    $connection = $manager->getConnection();
2129
    $config = new \Doctrine\DBAL\Migrations\Configuration\Configuration($connection);
2130
2131
    // Table name that will store migrations log (will be created automatically,
2132
    // default name is: doctrine_migration_versions)
2133
    $config->setMigrationsTableName('version');
2134
    // Namespace of your migration classes, do not forget escape slashes, do not add last slash
2135
    $config->setMigrationsNamespace('Application\Migrations\Schema\V'.$chamiloVersion);
2136
    // Directory where your migrations are located
2137
    $config->setMigrationsDirectory(api_get_path(SYS_PATH).'app/Migrations/Schema/V'.$chamiloVersion);
2138
    // Load your migrations
2139
    $config->registerMigrationsFromDirectory($config->getMigrationsDirectory());
2140
2141
    $migration = new \Doctrine\DBAL\Migrations\Migration($config);
2142
    $versions = $config->getMigrations();
2143
2144
    /** @var Doctrine\DBAL\Migrations\Version $migrationItem */
2145
    foreach ($versions as $version) {
2146
        $version->getMigration()->setEntityManager($manager);
2147
    }
2148
    $to = null; // if $to == null then schema will be migrated to latest version
2149
    echo "<pre>";
2150
    try {
2151
        // Execute migration!
2152
        $migratedSQL = $migration->migrate($to);
2153
2154
        if ($debug) {
2155
            foreach ($migratedSQL as $version => $sqlList) {
2156
                echo "VERSION: $version<br>";
2157
                echo "----------------------------------------------<br>";
2158
                $total = count($sqlList);
2159
                error_log("VERSION: $version");
2160
                error_log("# queries: ".$total);
2161
                $counter = 1;
2162
                foreach ($sqlList as $sql) {
2163
                    echo "<code>$sql</code><br>";
2164
                    error_log("$counter/$total : $sql");
2165
                    $counter++;
2166
                }
2167
            }
2168
            echo "<br>DONE!<br>";
2169
        }
2170
2171
        return true;
2172
    } catch (Exception $ex) {
2173
        if ($debug) {
2174
            echo "ERROR: {$ex->getMessage()}<br>";
2175
2176
            return false;
2177
        }
2178
    }
2179
    echo "</pre>";
2180
2181
    return false;
2182
}
2183
2184
/**
2185
 * @param EntityManager $em
2186
 *
2187
 * @throws \Doctrine\DBAL\DBALException
2188
 */
2189
function fixIds(EntityManager $em)
2190
{
2191
    $connection = $em->getConnection();
2192
    $database = new Database();
2193
    $database->setManager($em);
2194
    $debug = true;
2195
    if ($debug) {
2196
        error_log('fixIds');
2197
    }
2198
2199
    // Create temporary indexes to increase speed of the following operations
2200
    // Adding and removing indexes will usually take much less time than
2201
    // the execution without indexes of the queries in this function, particularly
2202
    // for large tables
2203
    $sql = "ALTER TABLE c_document ADD INDEX tmpidx_doc(c_id, id)";
2204
    $connection->executeQuery($sql);
2205
    $sql = "ALTER TABLE c_student_publication ADD INDEX tmpidx_stud (c_id, id)";
2206
    $connection->executeQuery($sql);
2207
    $sql = "ALTER TABLE c_quiz ADD INDEX tmpidx_quiz (c_id, id)";
2208
    $connection->executeQuery($sql);
2209
    $sql = "ALTER TABLE c_item_property ADD INDEX tmpidx_ip (to_group_id)";
2210
    $connection->executeQuery($sql);
2211
2212
    $sql = "SELECT * FROM c_lp_item";
2213
    $result = $connection->fetchAll($sql);
2214
    foreach ($result as $item) {
2215
        $courseId = $item['c_id'];
2216
        $iid = isset($item['iid']) ? intval($item['iid']) : 0;
2217
        $ref = isset($item['ref']) ? intval($item['ref']) : 0;
2218
        $sql = null;
2219
2220
        $newId = '';
2221
2222
        switch ($item['item_type']) {
2223
            case TOOL_LINK:
2224
                $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref";
2225
                $data = $connection->fetchAssoc($sql);
2226
                if ($data) {
2227
                    $newId = $data['iid'];
2228
                }
2229
                break;
2230
            case TOOL_STUDENTPUBLICATION:
2231
                $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref";
2232
                $data = $connection->fetchAssoc($sql);
2233
                if ($data) {
2234
                    $newId = $data['iid'];
2235
                }
2236
                break;
2237
            case TOOL_QUIZ:
2238
                $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref";
2239
                $data = $connection->fetchAssoc($sql);
2240
                if ($data) {
2241
                    $newId = $data['iid'];
2242
                }
2243
                break;
2244
            case TOOL_DOCUMENT:
2245
                $sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref";
2246
                $data = $connection->fetchAssoc($sql);
2247
                if ($data) {
2248
                    $newId = $data['iid'];
2249
                }
2250
                break;
2251
            case TOOL_FORUM:
2252
                $sql = "SELECT * FROM c_forum_forum WHERE c_id = $courseId AND forum_id = $ref";
2253
                $data = $connection->fetchAssoc($sql);
2254
                if ($data) {
2255
                    $newId = $data['iid'];
2256
                }
2257
                break;
2258
            case 'thread':
2259
                $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND thread_id = $ref";
2260
                $data = $connection->fetchAssoc($sql);
2261
                if ($data) {
2262
                    $newId = $data['iid'];
2263
                }
2264
                break;
2265
        }
2266
2267
        if (!empty($sql) && !empty($newId) && !empty($iid)) {
2268
            $sql = "UPDATE c_lp_item SET ref = $newId WHERE iid = $iid";
2269
2270
            $connection->executeQuery($sql);
2271
        }
2272
    }
2273
2274
    // Set NULL if session = 0
2275
    $sql = "UPDATE c_item_property SET session_id = NULL WHERE session_id = 0";
2276
    $connection->executeQuery($sql);
2277
2278
    // Set NULL if group = 0
2279
    $sql = "UPDATE c_item_property SET to_group_id = NULL WHERE to_group_id = 0";
2280
    $connection->executeQuery($sql);
2281
2282
    // Set NULL if insert_user_id = 0
2283
    $sql = "UPDATE c_item_property SET insert_user_id = NULL WHERE insert_user_id = 0";
2284
    $connection->executeQuery($sql);
2285
2286
    // Delete session data of sessions that don't exist.
2287
    $sql = "DELETE FROM c_item_property
2288
            WHERE session_id IS NOT NULL AND session_id NOT IN (SELECT id FROM session)";
2289
    $connection->executeQuery($sql);
2290
2291
    // Delete group data of groups that don't exist.
2292
    $sql = "DELETE FROM c_item_property
2293
            WHERE to_group_id IS NOT NULL AND to_group_id NOT IN (SELECT DISTINCT id FROM c_group_info)";
2294
    $connection->executeQuery($sql);
2295
2296
    // This updates the group_id with c_group_info.iid instead of c_group_info.id
2297
2298
    if ($debug) {
2299
        error_log('update iids');
2300
    }
2301
2302
    $groupTableToFix = [
2303
        'c_group_rel_user',
2304
        'c_group_rel_tutor',
2305
        'c_permission_group',
2306
        'c_role_group',
2307
        'c_survey_invitation',
2308
        'c_attendance_calendar_rel_group',
2309
    ];
2310
2311
    foreach ($groupTableToFix as $table) {
2312
        $sql = "SELECT * FROM $table";
2313
        $result = $connection->fetchAll($sql);
2314
        foreach ($result as $item) {
2315
            $iid = $item['iid'];
2316
            $courseId = $item['c_id'];
2317
            $groupId = intval($item['group_id']);
2318
2319
            // Fix group id
2320
            if (!empty($groupId)) {
2321
                $sql = "SELECT * FROM c_group_info
2322
                        WHERE c_id = $courseId AND id = $groupId
2323
                        LIMIT 1";
2324
                $data = $connection->fetchAssoc($sql);
2325
                if (!empty($data)) {
2326
                    $newGroupId = $data['iid'];
2327
                    $sql = "UPDATE $table SET group_id = $newGroupId
2328
                            WHERE iid = $iid";
2329
                    $connection->executeQuery($sql);
2330
                } else {
2331
                    // The group does not exists clean this record
2332
                    $sql = "DELETE FROM $table WHERE iid = $iid";
2333
                    $connection->executeQuery($sql);
2334
                }
2335
            }
2336
        }
2337
    }
2338
2339
    // Fix c_item_property
2340
    if ($debug) {
2341
        error_log('update c_item_property');
2342
    }
2343
2344
    $sql = "SELECT * FROM course";
2345
    $courseList = $connection->fetchAll($sql);
2346
    if ($debug) {
2347
        error_log('Getting course list');
2348
    }
2349
2350
    $totalCourse = count($courseList);
2351
    $counter = 0;
2352
2353
    foreach ($courseList as $courseData) {
2354
        $courseId = $courseData['id'];
2355
        if ($debug) {
2356
            error_log('Updating course: '.$courseData['code']);
2357
        }
2358
2359
        $sql = "SELECT * FROM c_item_property WHERE c_id = $courseId";
2360
        $result = $connection->fetchAll($sql);
2361
        foreach ($result as $item) {
2362
            $sessionId = intval($item['session_id']);
2363
            $groupId = intval($item['to_group_id']);
2364
            $iid = $item['iid'];
2365
            $ref = $item['ref'];
2366
2367
            // Fix group id
2368
            if (!empty($groupId)) {
2369
                $sql = "SELECT * FROM c_group_info
2370
                        WHERE c_id = $courseId AND id = $groupId";
2371
                $data = $connection->fetchAssoc($sql);
2372
                if (!empty($data)) {
2373
                    $newGroupId = $data['iid'];
2374
                    $sql = "UPDATE c_item_property SET to_group_id = $newGroupId
2375
                            WHERE iid = $iid";
2376
                    $connection->executeQuery($sql);
2377
                } else {
2378
                    // The group does not exists clean this record
2379
                    $sql = "DELETE FROM c_item_property WHERE iid = $iid";
2380
                    $connection->executeQuery($sql);
2381
                }
2382
            }
2383
2384
            $sql = '';
2385
            $newId = '';
2386
            switch ($item['tool']) {
2387
                case TOOL_LINK:
2388
                    $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref ";
2389
                    break;
2390
                case TOOL_STUDENTPUBLICATION:
2391
                    $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref";
2392
                    break;
2393
                case TOOL_QUIZ:
2394
                    $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref";
2395
                    break;
2396
                case TOOL_DOCUMENT:
2397
                    $sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref";
2398
                    break;
2399
                case TOOL_FORUM:
2400
                    $sql = "SELECT * FROM c_forum_forum WHERE c_id = $courseId AND id = $ref";
2401
                    break;
2402
                case 'thread':
2403
                    $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND id = $ref";
2404
                    break;
2405
            }
2406
2407
            if (!empty($sql) && !empty($newId)) {
2408
                $data = $connection->fetchAssoc($sql);
2409
                if (isset($data['iid'])) {
2410
                    $newId = $data['iid'];
2411
                }
2412
                $sql = "UPDATE c_item_property SET ref = $newId WHERE iid = $iid";
2413
                error_log($sql);
2414
                $connection->executeQuery($sql);
2415
            }
2416
        }
2417
2418
        if ($debug) {
2419
            // Print a status in the log once in a while
2420
            error_log("Course process #$counter/$totalCourse");
2421
        }
2422
        $counter++;
2423
    }
2424
2425
    if ($debug) {
2426
        error_log('update gradebook_link');
2427
    }
2428
2429
    // Fix gradebook_link
2430
    $sql = "SELECT * FROM gradebook_link";
2431
    $result = $connection->fetchAll($sql);
2432
    foreach ($result as $item) {
2433
        $courseCode = $item['course_code'];
2434
2435
        $sql = "SELECT * FROM course WHERE code = '$courseCode'";
2436
        $courseInfo = $connection->fetchAssoc($sql);
2437
        if (empty($courseInfo)) {
2438
            continue;
2439
        }
2440
2441
        $courseId = $courseInfo['id'];
2442
2443
        $ref = $item['ref_id'];
2444
        $iid = $item['id'];
2445
2446
        $sql = '';
2447
        switch ($item['type']) {
2448
            case LINK_LEARNPATH:
2449
                $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref ";
2450
                break;
2451
            case LINK_STUDENTPUBLICATION:
2452
                $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref";
2453
                break;
2454
            case LINK_EXERCISE:
2455
                $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref";
2456
                break;
2457
            case LINK_ATTENDANCE:
2458
                //$sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref";
2459
                break;
2460
            case LINK_FORUM_THREAD:
2461
                $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND thread_id = $ref";
2462
                break;
2463
        }
2464
2465
        if (!empty($sql)) {
2466
            $data = $connection->fetchAssoc($sql);
2467
            if (isset($data) && isset($data['iid'])) {
2468
                $newId = $data['iid'];
2469
                $sql = "UPDATE gradebook_link SET ref_id = $newId
2470
                        WHERE id = $iid";
2471
                $connection->executeQuery($sql);
2472
            }
2473
        }
2474
    }
2475
2476
    if ($debug) {
2477
        error_log('update groups');
2478
    }
2479
2480
    $sql = "SELECT * FROM groups";
2481
    $result = $connection->executeQuery($sql);
2482
    $groups = $result->fetchAll();
2483
2484
    $oldGroups = [];
2485
2486
    if (!empty($groups)) {
2487
        foreach ($groups as $group) {
2488
            if (empty($group['name'])) {
2489
                continue;
2490
            }
2491
2492
            $params = [
2493
                'name' => $group['name'],
2494
                'description' => $group['description'],
2495
                'group_type' => 1,
2496
                'picture' => $group['picture_uri'],
2497
                'url' => $group['url'],
2498
                'visibility' => $group['visibility'],
2499
                'updated_at' => $group['updated_on'],
2500
                'created_at' => $group['created_on'],
2501
            ];
2502
            $connection->insert('usergroup', $params);
2503
            $id = $connection->lastInsertId('id');
2504
            $oldGroups[$group['id']] = $id;
2505
        }
2506
    }
2507
2508
    if (!empty($oldGroups)) {
2509
        error_log('Moving group files');
2510
        foreach ($oldGroups as $oldId => $newId) {
2511
            $path = get_group_picture_path_by_id(
2512
                $oldId,
2513
                'system'
2514
            );
2515
2516
            if (!empty($path)) {
2517
                $newPath = str_replace(
2518
                    "groups/$oldId/",
2519
                    "groups/$newId/",
2520
                    $path['dir']
2521
                );
2522
                $command = "mv {$path['dir']} $newPath ";
2523
                error_log("Executing $command");
2524
                system($command);
2525
            }
2526
        }
2527
2528
        $sql = "SELECT * FROM group_rel_user";
2529
        $result = $connection->executeQuery($sql);
2530
        $dataList = $result->fetchAll();
2531
2532
        if (!empty($dataList)) {
2533
            foreach ($dataList as $data) {
2534
                if (isset($oldGroups[$data['group_id']])) {
2535
                    $data['group_id'] = $oldGroups[$data['group_id']];
2536
                    $userId = $data['user_id'];
2537
2538
                    $sql = "SELECT id FROM user WHERE user_id = $userId";
2539
                    $userResult = $connection->executeQuery($sql);
2540
                    $userInfo = $userResult->fetch();
2541
                    if (empty($userInfo)) {
2542
                        continue;
2543
                    }
2544
2545
                    $sql = "INSERT INTO usergroup_rel_user (usergroup_id, user_id, relation_type)
2546
                            VALUES ('{$data['group_id']}', '{$userId}', '{$data['relation_type']}')";
2547
                    $connection->executeQuery($sql);
2548
                }
2549
            }
2550
        }
2551
2552
        $sql = "SELECT * FROM group_rel_group";
2553
        $result = $connection->executeQuery($sql);
2554
        $dataList = $result->fetchAll();
2555
2556
        if (!empty($dataList)) {
2557
            foreach ($dataList as $data) {
2558
                if (isset($oldGroups[$data['group_id']]) && isset($oldGroups[$data['subgroup_id']])) {
2559
                    $data['group_id'] = $oldGroups[$data['group_id']];
2560
                    $data['subgroup_id'] = $oldGroups[$data['subgroup_id']];
2561
                    $sql = "INSERT INTO usergroup_rel_usergroup (group_id, subgroup_id, relation_type)
2562
                            VALUES ('{$data['group_id']}', '{$data['subgroup_id']}', '{$data['relation_type']}')";
2563
                    $connection->executeQuery($sql);
2564
                }
2565
            }
2566
        }
2567
2568
        $sql = "SELECT * FROM announcement_rel_group";
2569
        $result = $connection->executeQuery($sql);
2570
        $dataList = $result->fetchAll();
2571
2572
        if (!empty($dataList)) {
2573
            foreach ($dataList as $data) {
2574
                if (isset($oldGroups[$data['group_id']])) {
2575
                    // Deleting relation
2576
                    $sql = "DELETE FROM announcement_rel_group WHERE group_id = {$data['group_id']}";
2577
                    $connection->executeQuery($sql);
2578
2579
                    // Add new relation
2580
                    $data['group_id'] = $oldGroups[$data['group_id']];
2581
                    $sql = "INSERT INTO announcement_rel_group(group_id, announcement_id)
2582
                            VALUES ('{$data['group_id']}', '{$data['announcement_id']}')";
2583
                    $connection->executeQuery($sql);
2584
                }
2585
            }
2586
        }
2587
2588
        $sql = "SELECT * FROM group_rel_tag";
2589
        $result = $connection->executeQuery($sql);
2590
        $dataList = $result->fetchAll();
2591
        if (!empty($dataList)) {
2592
            foreach ($dataList as $data) {
2593
                if (isset($oldGroups[$data['group_id']])) {
2594
                    $data['group_id'] = $oldGroups[$data['group_id']];
2595
                    $sql = "INSERT INTO usergroup_rel_tag (tag_id, usergroup_id)
2596
                            VALUES ('{$data['tag_id']}', '{$data['group_id']}')";
2597
                    $connection->executeQuery($sql);
2598
                }
2599
            }
2600
        }
2601
    }
2602
2603
    if ($debug) {
2604
        error_log('update extra fields');
2605
    }
2606
2607
    // Extra fields
2608
    $extraFieldTables = [
2609
        ExtraField::USER_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_USER_FIELD),
2610
        ExtraField::COURSE_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_COURSE_FIELD),
2611
        //ExtraField::LP_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_LP_FIELD),
2612
        ExtraField::SESSION_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_SESSION_FIELD),
2613
        //ExtraField::CALENDAR_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_FIELD),
2614
        //ExtraField::QUESTION_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_FIELD),
2615
        //ExtraField::USER_FIELD_TYPE => //Database::get_main_table(TABLE_MAIN_SPECIFIC_FIELD),
2616
    ];
2617
2618
    foreach ($extraFieldTables as $type => $table) {
2619
        $sql = "SELECT * FROM $table ";
2620
        if ($debug) {
2621
            error_log($sql);
2622
        }
2623
        $result = $connection->query($sql);
2624
        $fields = $result->fetchAll();
2625
2626
        foreach ($fields as $field) {
2627
            if ($debug) {
2628
                error_log("Loading field: ".$field['field_variable']);
2629
            }
2630
            $originalId = $field['id'];
2631
2632
            $params = [
2633
                'extra_field_type' => $type,
2634
                'variable' => $field['field_variable'],
2635
                'field_type' => $field['field_type'],
2636
                'display_text' => $field['field_display_text'],
2637
                'default_value' => $field['field_default_value'],
2638
                'field_order' => $field['field_order'],
2639
                'visible' => $field['field_visible'],
2640
                'changeable' => $field['field_changeable'],
2641
                'filter' => $field['field_filter'],
2642
            ];
2643
2644
            $connection->insert('extra_field', $params);
2645
            $newExtraFieldId = $connection->lastInsertId();
2646
2647
            $values = [];
2648
            $handlerId = null;
2649
            switch ($type) {
2650
                case ExtraField::USER_FIELD_TYPE:
2651
                    $optionTable = Database::get_main_table(
2652
                        TABLE_MAIN_USER_FIELD_OPTIONS
2653
                    );
2654
                    $valueTable = Database::get_main_table(
2655
                        TABLE_MAIN_USER_FIELD_VALUES
2656
                    );
2657
                    $handlerId = 'user_id';
2658
                    break;
2659
                case ExtraField::COURSE_FIELD_TYPE:
2660
                    $optionTable = Database::get_main_table(
2661
                        TABLE_MAIN_COURSE_FIELD_OPTIONS
2662
                    );
2663
                    $valueTable = Database::get_main_table(
2664
                        TABLE_MAIN_COURSE_FIELD_VALUES
2665
                    );
2666
                    $handlerId = 'c_id';
2667
                    break;
2668
                case ExtraField::SESSION_FIELD_TYPE:
2669
                    $optionTable = Database::get_main_table(
2670
                        TABLE_MAIN_SESSION_FIELD_OPTIONS
2671
                    );
2672
                    $valueTable = Database::get_main_table(
2673
                        TABLE_MAIN_SESSION_FIELD_VALUES
2674
                    );
2675
                    $handlerId = 'session_id';
2676
                    break;
2677
            }
2678
2679
            if (!empty($optionTable)) {
2680
                $sql = "SELECT * FROM $optionTable WHERE field_id = $originalId ";
2681
                $result = $connection->query($sql);
2682
                $options = $result->fetchAll();
2683
2684
                foreach ($options as $option) {
2685
                    $params = [
2686
                        'display_text' => $option['option_display_text'],
2687
                        'field_id' => $newExtraFieldId,
2688
                        'option_order' => $option['option_order'],
2689
                        'option_value' => $option['option_value'],
2690
                    ];
2691
                    $connection->insert('extra_field_options', $params);
2692
                }
2693
2694
                $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...
2695
                $result = $connection->query($sql);
2696
                $values = $result->fetchAll();
2697
                if ($debug) {
2698
                    error_log("Fetch all values for field");
2699
                }
2700
            }
2701
2702
            if (!empty($values)) {
2703
                if ($debug) {
2704
                    error_log("Saving field value in new table");
2705
                }
2706
                $k = 0;
2707
                foreach ($values as $value) {
2708
                    if (isset($value[$handlerId])) {
2709
                        // Insert without the use of the entity as it reduces
2710
                        // speed to 2 records per second (much too slow)
2711
                        $params = [
2712
                            'field_id' => $newExtraFieldId,
2713
                            'value' => $value['field_value'],
2714
                            'item_id' => $value[$handlerId],
2715
                        ];
2716
                        $connection->insert('extra_field_values', $params);
2717
                        if ($debug && ($k % 10000 == 0)) {
2718
                            error_log("Saving field $k");
2719
                        }
2720
                        $k++;
2721
                    }
2722
                }
2723
            }
2724
        }
2725
    }
2726
2727
    if ($debug) {
0 ignored issues
show
introduced by
$debug is of type mixed, thus it always evaluated to true.
Loading history...
2728
        error_log('Remove index');
2729
    }
2730
2731
    // Drop temporary indexes added to increase speed of this function's queries
2732
    $sql = "ALTER TABLE c_document DROP INDEX tmpidx_doc";
2733
    $connection->executeQuery($sql);
2734
    $sql = "ALTER TABLE c_student_publication DROP INDEX tmpidx_stud";
2735
    $connection->executeQuery($sql);
2736
    $sql = "ALTER TABLE c_quiz DROP INDEX tmpidx_quiz";
2737
    $connection->executeQuery($sql);
2738
    $sql = "ALTER TABLE c_item_property DROP INDEX tmpidx_ip";
2739
    $connection->executeQuery($sql);
2740
2741
    if ($debug) {
2742
        error_log('Finish fixId function');
2743
    }
2744
}
2745
2746
/**
2747
 * @param string $distFile
2748
 * @param string $envFile
2749
 * @param array  $params
2750
 */
2751
function updateEnvFile($distFile, $envFile, $params)
2752
{
2753
    $contents = file_get_contents($distFile);
2754
    $contents = str_replace(array_keys($params), array_values($params), $contents);
2755
    file_put_contents($envFile, $contents);
2756
}
2757
2758
/**
2759
 * After the schema was created (table creation), the function adds
2760
 * admin/platform information.
2761
 *
2762
 * @param \Psr\Container\ContainerInterface $container
2763
 * @param string                            $sysPath
2764
 * @param string                            $encryptPassForm
2765
 * @param string                            $passForm
2766
 * @param string                            $adminLastName
2767
 * @param string                            $adminFirstName
2768
 * @param string                            $loginForm
2769
 * @param string                            $emailForm
2770
 * @param string                            $adminPhoneForm
2771
 * @param string                            $languageForm
2772
 * @param string                            $institutionForm
2773
 * @param string                            $institutionUrlForm
2774
 * @param string                            $siteName
2775
 * @param string                            $allowSelfReg
2776
 * @param string                            $allowSelfRegProf
2777
 * @param string                            $installationProfile Installation profile, if any was provided
2778
 */
2779
function finishInstallationWithContainer(
2780
    $container,
2781
    $sysPath,
2782
    $encryptPassForm,
2783
    $passForm,
2784
    $adminLastName,
2785
    $adminFirstName,
2786
    $loginForm,
2787
    $emailForm,
2788
    $adminPhoneForm,
2789
    $languageForm,
2790
    $institutionForm,
2791
    $institutionUrlForm,
2792
    $siteName,
2793
    $allowSelfReg,
2794
    $allowSelfRegProf,
2795
    $installationProfile = ''
2796
) {
2797
    $sysPath = !empty($sysPath) ? $sysPath : api_get_path(SYS_PATH);
2798
    Container::setContainer($container);
2799
    Container::setLegacyServices($container);
2800
2801
    $manager = Database::getManager();
2802
    $connection = $manager->getConnection();
2803
    $siteManager = Container::getSiteManager();
2804
    $settingsManager = Container::getSettingsManager();
2805
2806
    $sql = getVersionTable();
2807
2808
    // Add version table
2809
    $connection->executeQuery($sql);
2810
2811
    // Add tickets defaults
2812
    $ticketProject = new TicketProject();
2813
    $ticketProject
2814
        ->setId(1)
2815
        ->setName('Ticket System')
2816
        ->setInsertUserId(1);
2817
2818
    $manager->persist($ticketProject);
2819
    $manager->flush();
2820
2821
    $categories = [
2822
        get_lang('TicketEnrollment') => get_lang('TicketsAboutEnrollment'),
2823
        get_lang('TicketGeneralInformation') => get_lang('TicketsAboutGeneralInformation'),
2824
        get_lang('TicketRequestAndPapework') => get_lang('TicketsAboutRequestAndPapework'),
2825
        get_lang('TicketAcademicIncidence') => get_lang('TicketsAboutAcademicIncidence'),
2826
        get_lang('TicketVirtualCampus') => get_lang('TicketsAboutVirtualCampus'),
2827
        get_lang('TicketOnlineEvaluation') => get_lang('TicketsAboutOnlineEvaluation'),
2828
    ];
2829
2830
    $i = 1;
2831
    foreach ($categories as $category => $description) {
2832
        // Online evaluation requires a course
2833
        $ticketCategory = new TicketCategory();
2834
        $ticketCategory
2835
            ->setId($i)
2836
            ->setName($category)
2837
            ->setDescription($description)
2838
            ->setProject($ticketProject)
2839
            ->setInsertUserId(1);
2840
2841
        $isRequired = $i == 6;
2842
        $ticketCategory->setCourseRequired($isRequired);
2843
2844
        $manager->persist($ticketCategory);
2845
        $manager->flush();
2846
2847
        $i++;
2848
    }
2849
2850
    // Default Priorities
2851
    $defaultPriorities = [
2852
        TicketManager::PRIORITY_NORMAL => get_lang('PriorityNormal'),
2853
        TicketManager::PRIORITY_HIGH => get_lang('PriorityHigh'),
2854
        TicketManager::PRIORITY_LOW => get_lang('PriorityLow'),
2855
    ];
2856
2857
    $i = 1;
2858
    foreach ($defaultPriorities as $code => $priority) {
2859
        $ticketPriority = new TicketPriority();
2860
        $ticketPriority
2861
            ->setId($i)
2862
            ->setName($priority)
2863
            ->setCode($code)
2864
            ->setInsertUserId(1);
2865
2866
        $manager->persist($ticketPriority);
2867
        $manager->flush();
2868
        $i++;
2869
    }
2870
2871
    $table = Database::get_main_table(TABLE_TICKET_STATUS);
2872
2873
    // Default status
2874
    $defaultStatus = [
2875
        TicketManager::STATUS_NEW => get_lang('StatusNew'),
2876
        TicketManager::STATUS_PENDING => get_lang('StatusPending'),
2877
        TicketManager::STATUS_UNCONFIRMED => get_lang('StatusUnconfirmed'),
2878
        TicketManager::STATUS_CLOSE => get_lang('StatusClose'),
2879
        TicketManager::STATUS_FORWARDED => get_lang('StatusForwarded'),
2880
    ];
2881
2882
    $i = 1;
2883
    foreach ($defaultStatus as $code => $status) {
2884
        $attributes = [
2885
            'id' => $i,
2886
            'code' => $code,
2887
            'name' => $status,
2888
        ];
2889
        Database::insert($table, $attributes);
2890
        $i++;
2891
    }
2892
2893
    // Creating AccessUrl
2894
    $accessUrl = new AccessUrl();
2895
    $accessUrl
2896
        ->setUrl('http://localhost/')
2897
        ->setDescription('')
2898
        ->setActive(1)
2899
    ;
2900
    $manager->persist($accessUrl);
2901
    $manager->flush();
2902
2903
    // Creating settings
2904
    $settingsManager->installSchemas($accessUrl);
2905
2906
    // Inserting data
2907
    $data = file_get_contents($sysPath.'main/install/data.sql');
2908
    $result = $manager->getConnection()->prepare($data);
2909
    $result->execute();
2910
    $result->closeCursor();
2911
2912
    // Create site
2913
2914
    /** @var Chamilo\PageBundle\Entity\Site $site */
2915
    $site = $siteManager->create();
2916
    $site->setHost('localhost');
2917
    $site->setEnabled(true);
2918
    $site->setName('localhost');
2919
    $site->setEnabledFrom(new \DateTime('now'));
2920
    $site->setEnabledTo(new \DateTime('+20 years'));
2921
    $site->setRelativePath('');
2922
    $site->setIsDefault(true);
2923
    $siteManager->save($site);
2924
2925
    // Create home page
2926
    /** @var PageManager $pageManager */
2927
    $pageManager = $container->get('sonata.page.manager.page');
2928
    /** @var \Sonata\PageBundle\Model\Page $page */
2929
    $page = $pageManager->create();
2930
    $page->setSlug('homepage');
2931
    $page->setUrl('/');
2932
    $page->setName('homepage');
2933
    $page->setTitle('home');
2934
    $page->setEnabled(true);
2935
    $page->setDecorate(1);
2936
    $page->setRequestMethod('GET|POST|HEAD|DELETE|PUT');
2937
    $page->setTemplateCode('default');
2938
    $page->setRouteName('homepage');
2939
    //$page->setParent($this->getReference('page-homepage'));
2940
    $page->setSite($site);
2941
    $pageManager->save($page);
2942
2943
    // Create welcome page
2944
    $pageWelcome = $pageManager->create();
2945
    $pageWelcome->setSlug('welcome');
2946
    $pageWelcome->setUrl('/welcome');
2947
    $pageWelcome->setName('welcome');
2948
    $pageWelcome->setTitle('welcome');
2949
    $pageWelcome->setEnabled(true);
2950
    $pageWelcome->setDecorate(1);
2951
    $pageWelcome->setRequestMethod('GET');
2952
    $pageWelcome->setTemplateCode('default');
2953
    $pageWelcome->setRouteName('welcome');
2954
    $pageWelcome->setParent($page);
2955
    $pageWelcome->setSite($site);
2956
2957
    $pageManager->save($pageWelcome);
2958
2959
    $templateManager = $container->get('sonata.page.template_manager');
2960
    $template = $templateManager->get('default');
2961
    $templateContainers = $template->getContainers();
2962
2963
    $containers = [];
2964
    foreach ($templateContainers as $id => $area) {
2965
        $containers[$id] = [
2966
            'area' => $area,
2967
            'block' => false,
2968
        ];
2969
    }
2970
2971
    // Create blocks for this page
2972
    $blockInteractor = $container->get('sonata.page.block_interactor');
2973
    $parentBlock = null;
2974
    foreach ($containers as $id => $area) {
2975
        if (false === $area['block'] && $templateContainers[$id]['shared'] === false) {
2976
            $block = $blockInteractor->createNewContainer(
2977
                [
2978
                    'page' => $pageWelcome,
2979
                    'name' => $templateContainers[$id]['name'],
2980
                    'code' => $id,
2981
                ]
2982
            );
2983
2984
            if ($id === 'content' && $templateContainers[$id]['name'] == 'Main content') {
2985
                $parentBlock = $block;
2986
            }
2987
        }
2988
    }
2989
2990
    // Create block in main content
2991
    $block = $container->get('sonata.page.manager.block');
2992
    /** @var \Sonata\BlockBundle\Model\Block $myBlock */
2993
    $myBlock = $block->create();
2994
    $myBlock->setType('sonata.formatter.block.formatter');
2995
    $myBlock->setSetting('format', 'richhtml');
2996
    $myBlock->setSetting('content', '');
2997
    $myBlock->setSetting('rawContent', '');
2998
    $myBlock->setSetting('template', '@SonataFormatter/Block/block_formatter.html.twig');
2999
    $myBlock->setParent($parentBlock);
3000
    $pageWelcome->addBlocks($myBlock);
3001
    $pageManager->save($pageWelcome);
3002
3003
    UserManager::setPasswordEncryption($encryptPassForm);
3004
3005
    // Create admin user.
3006
    @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

3006
    /** @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...
3007
        $adminFirstName,
3008
        $adminLastName,
3009
        1,
3010
        $emailForm,
3011
        $loginForm,
3012
        $passForm,
3013
        'ADMIN', //$official_code = '',
3014
        $languageForm,
3015
        $adminPhoneForm,
3016
        '', //$picture_uri = '',
3017
        PLATFORM_AUTH_SOURCE,
3018
        '', //$expirationDate,
3019
        1,
3020
        0,
3021
        null,
3022
        '',
3023
        false, //$send_mail = false,
3024
        true, //$isAdmin = false
3025
            '',
3026
        false,
3027
        '',
3028
        1
3029
    );
3030
3031
    // Create anonymous user.
3032
    @UserManager::create_user(
3033
        'Joe',
3034
        'Anonymous',
3035
        6,
3036
        'anonymous@localhost',
3037
        'anon',
3038
        'anon',
3039
        'anonymous', //$official_code = '',
3040
        $languageForm,
3041
        '',
3042
        '', //$picture_uri = '',
3043
        PLATFORM_AUTH_SOURCE,
3044
        '',
3045
        1,
3046
        0,
3047
        null,
3048
        '',
3049
        false, //$send_mail = false,
3050
        false, //$isAdmin = false
3051
        '',
3052
        false,
3053
        '',
3054
        1
3055
    );
3056
3057
    // Set default language
3058
    $sql = "UPDATE language SET available = 1 WHERE dokeos_folder = '$languageForm'";
3059
    Database::query($sql);
3060
3061
    // Install settings
3062
    installSettings(
3063
        $institutionForm,
3064
        $institutionUrlForm,
3065
        $siteName,
3066
        $emailForm,
3067
        $adminLastName,
3068
        $adminFirstName,
3069
        $languageForm,
3070
        $allowSelfReg,
3071
        $allowSelfRegProf,
3072
        $installationProfile
3073
    );
3074
3075
    lockSettings();
3076
    updateDirAndFilesPermissions();
3077
3078
    // Set the latest version
3079
    /*$path = $sysPath.'app/Migrations/Schema/V111/';
3080
    $finder = new \Symfony\Component\Finder\Finder();
3081
    $files = $finder->files()->in($path);
3082
3083
    // Needed for chash
3084
    createVersionTable();
3085
3086
    foreach ($files as $version) {
3087
        $version = str_replace(['Version', '.php'], '', $version->getFilename());
3088
        $sql = "INSERT INTO version (version) VALUES ('$version')";
3089
        Database::query($sql);
3090
    }*/
3091
}
3092
3093
/**
3094
 * Creates 'version' table.
3095
 */
3096
function createVersionTable()
3097
{
3098
    $sql = getVersionTable();
3099
    Database::query($sql);
3100
}
3101
3102
/**
3103
 * Get version creation table query.
3104
 *
3105
 * @return string
3106
 */
3107
function getVersionTable()
3108
{
3109
    return 'CREATE TABLE IF NOT EXISTS version (id int unsigned NOT NULL AUTO_INCREMENT, version varchar(20), PRIMARY KEY(id), UNIQUE(version));';
3110
}
3111
3112
/**
3113
 * Update settings based on installation profile defined in a JSON file.
3114
 *
3115
 * @param string $installationProfile The name of the JSON file in main/install/profiles/ folder
3116
 *
3117
 * @return bool false on failure (no bad consequences anyway, just ignoring profile)
3118
 */
3119
function installProfileSettings($installationProfile = '')
3120
{
3121
    if (empty($installationProfile)) {
3122
        return false;
3123
    }
3124
    $jsonPath = api_get_path(SYS_PATH).'main/install/profiles/'.$installationProfile.'.json';
3125
    // Make sure the path to the profile is not hacked
3126
    if (!Security::check_abs_path($jsonPath, api_get_path(SYS_PATH).'main/install/profiles/')) {
3127
        return false;
3128
    }
3129
    if (!is_file($jsonPath)) {
3130
        return false;
3131
    }
3132
    if (!is_readable($jsonPath)) {
3133
        return false;
3134
    }
3135
    if (!function_exists('json_decode')) {
3136
        // The php-json extension is not available. Ignore profile.
3137
        return false;
3138
    }
3139
    $json = file_get_contents($jsonPath);
3140
    $params = json_decode($json);
3141
    if ($params === false or $params === null) {
3142
        return false;
3143
    }
3144
    $settings = $params->params;
3145
    if (!empty($params->parent)) {
3146
        installProfileSettings($params->parent);
3147
    }
3148
    foreach ($settings as $id => $param) {
3149
        $sql = "UPDATE settings_current
3150
                SET selected_value = '".$param->selected_value."'
3151
                WHERE variable = '".$param->variable."'";
3152
        if (!empty($param->subkey)) {
3153
            $sql .= " AND subkey='".$param->subkey."'";
3154
        }
3155
        Database::query($sql);
3156
    }
3157
3158
    return true;
3159
}
3160
3161
/**
3162
 * Quick function to remove a directory with its subdirectories.
3163
 *
3164
 * @param $dir
3165
 */
3166
function rrmdir($dir)
3167
{
3168
    if (is_dir($dir)) {
3169
        $objects = scandir($dir);
3170
        foreach ($objects as $object) {
3171
            if ($object != "." && $object != "..") {
3172
                if (filetype($dir."/".$object) == "dir") {
3173
                    @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

3173
                    /** @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...
3174
                } else {
3175
                    @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

3175
                    /** @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...
3176
                }
3177
            }
3178
        }
3179
        reset($objects);
3180
        rmdir($dir);
3181
    }
3182
}
3183
3184
function get_group_picture_path_by_id($id, $type = 'web', $preview = false, $anonymous = false)
3185
{
3186
    switch ($type) {
3187
        case 'system': // Base: absolute system path.
3188
            $base = api_get_path(SYS_UPLOAD_PATH);
3189
            break;
3190
        case 'web': // Base: absolute web path.
3191
        default:
3192
            $base = api_get_path(WEB_UPLOAD_PATH);
3193
            break;
3194
    }
3195
3196
    $noPicturePath = ['dir' => $base.'img/', 'file' => 'unknown.jpg'];
3197
3198
    if (empty($id) || empty($type)) {
3199
        return $anonymous ? $noPicturePath : ['dir' => '', 'file' => ''];
3200
    }
3201
3202
    $id = intval($id);
3203
3204
    //$group_table = Database::get_main_table(TABLE_MAIN_GROUP);
3205
    $group_table = 'groups';
3206
    $sql = "SELECT picture_uri FROM $group_table WHERE id=".$id;
3207
    $res = Database::query($sql);
3208
3209
    if (!Database::num_rows($res)) {
3210
        return $anonymous ? $noPicturePath : ['dir' => '', 'file' => ''];
3211
    }
3212
3213
    $user = Database::fetch_array($res);
3214
    $picture_filename = trim($user['picture_uri']);
3215
3216
    if (api_get_setting('split_users_upload_directory') === 'true') {
3217
        if (!empty($picture_filename)) {
3218
            $dir = $base.'groups/'.substr($picture_filename, 0, 1).'/'.$id.'/';
3219
        } elseif ($preview) {
3220
            $dir = $base.'groups/'.substr((string) $id, 0, 1).'/'.$id.'/';
3221
        } else {
3222
            $dir = $base.'groups/'.$id.'/';
3223
        }
3224
    } else {
3225
        $dir = $base.'groups/'.$id.'/';
3226
    }
3227
3228
    if (empty($picture_filename) && $anonymous) {
3229
        return $noPicturePath;
3230
    }
3231
3232
    return ['dir' => $dir, 'file' => $picture_filename];
3233
}
3234
3235
/**
3236
 * Control the different steps of the migration through a big switch.
3237
 *
3238
 * @param string        $fromVersion
3239
 * @param EntityManager $manager
3240
 * @param bool          $processFiles
3241
 *
3242
 * @return bool Always returns true except if the process is broken
3243
 */
3244
function migrateSwitch($fromVersion, $manager, $processFiles = true)
3245
{
3246
    error_log('Starting migration process from '.$fromVersion.' ('.date('Y-m-d H:i:s').')');
3247
3248
    echo '<a class="btn btn-default" href="javascript:void(0)" id="details_button">'.get_lang('Details').'</a><br />';
3249
    echo '<div id="details" style="display:none">';
3250
3251
    $connection = $manager->getConnection();
3252
3253
    $database = new Database();
3254
    $database->setManager($manager);
3255
3256
    switch ($fromVersion) {
3257
        case '1.9.0':
3258
        case '1.9.2':
3259
        case '1.9.4':
3260
        case '1.9.6':
3261
        case '1.9.6.1':
3262
        case '1.9.8':
3263
        case '1.9.8.1':
3264
        case '1.9.8.2':
3265
        case '1.9.10':
3266
        case '1.9.10.2':
3267
        case '1.9.10.4':
3268
        case '1.9.10.6':
3269
            $database = new Database();
3270
            $database->setManager($manager);
3271
3272
            // Fix type "enum" before running the migration with Doctrine
3273
            $connection->executeQuery("ALTER TABLE course_category MODIFY COLUMN auth_course_child VARCHAR(40) DEFAULT 'TRUE'");
3274
            $connection->executeQuery("ALTER TABLE course_category MODIFY COLUMN auth_cat_child VARCHAR(40) DEFAULT 'TRUE'");
3275
            $connection->executeQuery("ALTER TABLE c_quiz_answer MODIFY COLUMN hotspot_type varchar(40) default NULL");
3276
            $connection->executeQuery("ALTER TABLE c_tool MODIFY COLUMN target varchar(20) NOT NULL default '_self'");
3277
            $connection->executeQuery("ALTER TABLE c_link MODIFY COLUMN on_homepage char(10) NOT NULL default '0'");
3278
            $connection->executeQuery("ALTER TABLE c_blog_rating MODIFY COLUMN rating_type char(40) NOT NULL default 'post'");
3279
            $connection->executeQuery("ALTER TABLE c_survey MODIFY COLUMN anonymous char(10) NOT NULL default '0'");
3280
            $connection->executeQuery("ALTER TABLE c_document MODIFY COLUMN filetype char(10) NOT NULL default 'file'");
3281
            $connection->executeQuery("ALTER TABLE c_student_publication MODIFY COLUMN filetype char(10) NOT NULL default 'file'");
3282
3283
            // Migrate using the migration files located in:
3284
            // src/Chamilo/CoreBundle/Migrations/Schema/V110
3285
            $result = migrate(
3286
                110,
3287
                $manager
3288
            );
3289
3290
            if ($result) {
3291
                error_log('Migrations files were executed ('.date('Y-m-d H:i:s').')');
3292
                fixIds($manager);
3293
                error_log('fixIds finished ('.date('Y-m-d H:i:s').')');
3294
3295
                $connection->executeQuery("UPDATE settings_current SET selected_value = '1.10.0' WHERE variable = 'chamilo_database_version'");
3296
3297
                if ($processFiles) {
3298
                    $fromVersionShort = '1.9';
3299
                    include __DIR__.'/update-files-1.9.0-1.10.0.inc.php';
3300
                    // Only updates the configuration.inc.php with the new version
3301
                    include __DIR__.'/update-configuration.inc.php';
3302
3303
                    $configurationFiles = [
3304
                        'mail.conf.php',
3305
                        'profile.conf.php',
3306
                        'course_info.conf.php',
3307
                        'add_course.conf.php',
3308
                        'events.conf.php',
3309
                        'auth.conf.php',
3310
                    ];
3311
3312
                    error_log('Copy conf files');
3313
3314
                    foreach ($configurationFiles as $file) {
3315
                        if (file_exists(api_get_path(SYS_CODE_PATH).'inc/conf/'.$file)) {
3316
                            copy(
3317
                                api_get_path(SYS_CODE_PATH).'inc/conf/'.$file,
3318
                                api_get_path(CONFIGURATION_PATH).$file
3319
                            );
3320
                        }
3321
                    }
3322
                }
3323
3324
                error_log('Upgrade 1.10.x process concluded! ('.date('Y-m-d H:i:s').')');
3325
            } else {
3326
                error_log('There was an error during running migrations. Check error.log');
3327
                break;
3328
            }
3329
            // no break
3330
        case '1.10.0':
3331
        case '1.10.2':
3332
        case '1.10.4':
3333
        case '1.10.6':
3334
        case '1.10.8':
3335
        case '1.10.8':
3336
            $database = new Database();
3337
            $database->setManager($manager);
3338
            // Migrate using the migration files located in:
3339
            // src/Chamilo/CoreBundle/Migrations/Schema/V111
3340
            $result = migrate(
3341
                111,
3342
                $manager
3343
            );
3344
3345
            if ($result) {
3346
                error_log('Migrations files were executed ('.date('Y-m-d H:i:s').')');
3347
3348
                fixPostGroupIds($connection);
3349
3350
                $sql = "UPDATE settings_current SET selected_value = '1.11.0' WHERE variable = 'chamilo_database_version'";
3351
                $connection->executeQuery($sql);
3352
                if ($processFiles) {
3353
                    error_log('Update config files');
3354
                    $fromVersionShort = '1.10';
3355
                    include __DIR__.'/update-files-1.10.0-1.11.0.inc.php';
3356
                    // Only updates the configuration.inc.php with the new version
3357
                    include __DIR__.'/update-configuration.inc.php';
3358
                }
3359
                error_log('Upgrade 1.11.x process concluded!  ('.date('Y-m-d H:i:s').')');
3360
            } else {
3361
                error_log('There was an error during running migrations. Check error.log');
3362
            }
3363
            // no break
3364
        case '1.11.0':
3365
        case '1.11.1':
3366
        case '1.11.2':
3367
        case '1.11.4':
3368
        case '1.11.6':
3369
        case '1.11.8':
3370
        case '1.11.10':
3371
            $database = new Database();
3372
            $database->setManager($manager);
3373
            // Migrate using the migration files located in:
3374
            // src/Chamilo/CoreBundle/Migrations/Schema/V111
3375
            $result = migrate(
3376
                200,
3377
                $manager
3378
            );
3379
3380
            if ($result) {
3381
                error_log('Migrations files were executed ('.date('Y-m-d H:i:s').')');
3382
                $sql = "UPDATE settings_current SET selected_value = '2.0.0' WHERE variable = 'chamilo_database_version'";
3383
                $connection->executeQuery($sql);
3384
                if ($processFiles) {
3385
                    error_log('Update config files');
3386
                    $fromVersionShort = '1.10';
3387
                    include __DIR__.'/update-files-1.11.0-2.0.0.inc.php';
3388
                    // Only updates the configuration.inc.php with the new version
3389
                    include __DIR__.'/update-configuration.inc.php';
3390
                }
3391
                error_log('Upgrade 2.0.0 process concluded!  ('.date('Y-m-d H:i:s').')');
3392
            } else {
3393
                error_log('There was an error during running migrations. Check error.log');
3394
            }
3395
            break;
3396
        default:
3397
            break;
3398
    }
3399
3400
    echo '</div>';
3401
3402
    return true;
3403
}
3404
3405
/**
3406
 * @param \Doctrine\DBAL\Connection $connection
3407
 */
3408
function fixPostGroupIds($connection)
3409
{
3410
    $connection->executeQuery("ALTER TABLE course_category MODIFY COLUMN auth_course_child VARCHAR(40) DEFAULT 'TRUE'");
3411
    error_log('Fix c_student_publication.post_group_id');
3412
3413
    // Fix post_group_id
3414
    $sql = "SELECT * FROM c_student_publication 
3415
            WHERE (post_group_id <> 0 AND post_group_id is not null)";
3416
    $statement = $connection->executeQuery($sql);
3417
    $result = $statement->fetchAll();
3418
3419
    foreach ($result as $row) {
3420
        $groupId = $row['post_group_id'];
3421
        $courseId = $row['c_id'];
3422
        $workIid = $row['iid'];
3423
        $sql = "SELECT iid from c_group_info 
3424
                WHERE c_id = $courseId AND id = $groupId";
3425
        $statement = $connection->executeQuery($sql);
3426
        $count = $statement->rowCount();
3427
        if ($count > 0) {
3428
            $rowGroup = $statement->fetch();
3429
            $newGroupId = $rowGroup['iid'];
3430
            if ($newGroupId == $groupId) {
3431
                continue;
3432
            }
3433
            if ($newGroupId) {
3434
                $sql = "UPDATE c_student_publication 
3435
                        SET post_group_id = $newGroupId 
3436
                        WHERE 
3437
                            c_id = $courseId AND
3438
                            iid = $workIid
3439
                        ";
3440
                $connection->executeQuery($sql);
3441
            }
3442
        }
3443
    }
3444
3445
    error_log('End - Fix c_student_publication.post_group_id');
3446
3447
    // Delete c_student_publication from any session that doesn't exist anymore
3448
    $sql = "DELETE FROM c_student_publication 
3449
            WHERE session_id NOT IN (SELECT id FROM session) AND (session_id <> 0 AND session_id is not null)";
3450
    $connection->executeQuery($sql);
3451
3452
    error_log('Fix work documents');
3453
    // Fix work documents that don't have c_item_property value
3454
    $sql = "SELECT * FROM c_student_publication WHERE parent_id IS NOT NULL";
3455
    $statement = $connection->executeQuery($sql);
3456
    $result = $statement->fetchAll();
3457
    foreach ($result as $row) {
3458
        $groupId = $row['post_group_id'];
3459
        $courseId = $row['c_id'];
3460
        $sessionId = $row['session_id'];
3461
        $workId = $row['id'];
3462
        $itemInfo = api_get_item_property_info(
3463
            $courseId,
3464
            'work',
3465
            $workId,
3466
            $sessionId
3467
        );
3468
        $courseInfo = api_get_course_info_by_id($courseId);
3469
        if (empty($itemInfo)) {
3470
            api_item_property_update(
3471
                $courseInfo,
3472
                'work',
3473
                $workId,
3474
                'visible',
3475
                1,
3476
                $groupId,
3477
                null,
3478
                null,
3479
                null,
3480
                $sessionId
3481
            );
3482
        }
3483
    }
3484
    error_log('End - Fix work documents');
3485
}
3486