Test Setup Failed
Push — master ( 4e700f...c7183e )
by Julito
63:12
created

settings.lib.php ➔ getCategorySettings()   C

Complexity

Conditions 12
Paths 12

Size

Total Lines 51
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 30
nc 12
nop 1
dl 0
loc 51
rs 5.6668
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Symfony\Component\Filesystem\Filesystem;
5
use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
6
7
/**
8
 * Library of the settings.php file
9
 *
10
 * @author Julio Montoya <[email protected]>
11
 * @author Guillaume Viguier <[email protected]>
12
 *
13
 * @since Chamilo 1.8.7
14
 * @package chamilo.admin
15
 */
16
17
define('CSS_UPLOAD_PATH', api_get_path(SYS_APP_PATH).'Resources/public/css/themes/');
18
19
/**
20
 * This function allows easy activating and inactivating of regions
21
 * @author Julio Montoya <[email protected]> Beeznest 2012
22
 */
23
function handleRegions()
24
{
25
    if (isset($_POST['submit_plugins'])) {
26
        storeRegions();
27
        // Add event to the system log.
28
        $user_id = api_get_user_id();
29
        $category = $_GET['category'];
30
        Event::addEvent(
31
            LOG_CONFIGURATION_SETTINGS_CHANGE,
32
            LOG_CONFIGURATION_SETTINGS_CATEGORY,
33
            $category,
34
            api_get_utc_datetime(),
0 ignored issues
show
Bug introduced by
It seems like api_get_utc_datetime() can also be of type object<DateTime>; however, Event::addEvent() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
35
            $user_id
36
        );
37
        echo Display::return_message(get_lang('SettingsStored'), 'confirmation');
38
    }
39
40
    $plugin_obj = new AppPlugin();
41
    $possible_plugins  = $plugin_obj->read_plugins_from_path();
42
    $installed_plugins = $plugin_obj->get_installed_plugins();
43
    $name = isset($_GET['name']) ? $_GET['name'] : '';
44
45
    echo '<form 
46
        name="plugins" 
47
        method="post" 
48
        action="'.api_get_self().'?category='.Security::remove_XSS($_GET['category']).'&name='.Security::remove_XSS($name).'">';
49
    echo '<table class="data_table">';
50
    echo '<tr>';
51
    echo '<th width="400px">';
52
    echo get_lang('Plugin');
53
    echo '</th><th>';
54
    echo get_lang('Regions');
55
    echo '</th>';
56
    echo '</th>';
57
    echo '</tr>';
58
59
    /* We display all the possible plugins and the checkboxes */
60
61
    $plugin_region_list = array();
62
    $my_plugin_list = $plugin_obj->get_plugin_regions();
63
    foreach ($my_plugin_list as $plugin_item) {
64
        $plugin_region_list[$plugin_item] = $plugin_item;
65
    }
66
67
    // Removing course tool
68
    unset($plugin_region_list['course_tool_plugin']);
69
70
    foreach ($installed_plugins as $pluginName) {
71
        $plugin_info_file = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/plugin.php';
72
73
        if (file_exists($plugin_info_file)) {
74
            $plugin_info = array();
75
            require $plugin_info_file;
76
            if ($name === $pluginName) {
77
                echo '<tr class="row_selected">';
78
            } else {
79
                echo '<tr>';
80
            }
81
            echo '<td>';
82
            echo '<h4>'.$plugin_info['title'].' <small>v'.$plugin_info['version'].'</small></h4>';
83
            echo '<p>'.$plugin_info['comment'].'</p>';
84
            echo '</td><td>';
85
            $selected_plugins = $plugin_obj->get_areas_by_plugin($pluginName);
86
87
            $region_list = [];
88
89
            $isAdminPlugin = isset($plugin_info['is_admin_plugin']) && $plugin_info['is_admin_plugin'];
90
            $isCoursePlugin = isset($plugin_info['is_course_plugin']) && $plugin_info['is_course_plugin'];
91
92
            if (!$isAdminPlugin && !$isCoursePlugin) {
93
                $region_list = $plugin_region_list;
94
            } else {
95
                if ($isAdminPlugin) {
96
                    $region_list['menu_administrator'] = 'menu_administrator';
97
                }
98
                if ($isCoursePlugin) {
99
                    $region_list['course_tool_plugin'] = 'course_tool_plugin';
100
                }
101
            }
102
            echo Display::select(
103
                'plugin_'.$pluginName.'[]',
104
                $region_list,
105
                $selected_plugins,
106
                array('multiple' => 'multiple', 'style' => 'width:500px'),
107
                true,
108
                get_lang('None')
109
            );
110
            echo '</td></tr>';
111
        }
112
    }
113
    echo '</table>';
114
    echo '<br />';
115
    echo '<button class="btn btn-success" type="submit" name="submit_plugins">'.get_lang('EnablePlugins').'</button></form>';
116
}
117
118
function handleExtensions()
119
{
120
    echo Display::page_subheader(get_lang('ConfigureExtensions'));
121
    echo '<a class="btn btn-success" href="configure_extensions.php?display=ppt2lp" role="button">'.get_lang('Ppt2lp').'</a>';
122
123
}
124
125
/**
126
 * This function allows easy activating and inactivating of plugins
127
 * @todo: a similar function needs to be written to activate or inactivate additional tools.
128
 * @author Patrick Cool <[email protected]>, Ghent University
129
 * @author Julio Montoya <[email protected]> Beeznest 2012
130
 */
131
function handlePlugins($installed = true)
132
{
133
    $plugin_obj = new AppPlugin();
134
    $token = Security::get_token();
135
    if (isset($_REQUEST['action'])) {
136
        $name = $_REQUEST['name'];
137
        $appPlugin = new AppPlugin();
138
        switch ($_REQUEST['action']) {
139
            case 'install':
140
                $appPlugin->install($name);
141
                break;
142
            case 'uninstall':
143
                $appPlugin->uninstall($name);
144
                break;
145
        }
146
147
        // Add event to the system log.
148
        $user_id = api_get_user_id();
149
        $category = $_GET['category'];
150
        Event::addEvent(
151
            LOG_CONFIGURATION_SETTINGS_CHANGE,
152
            LOG_CONFIGURATION_SETTINGS_CATEGORY,
153
            $category,
154
            api_get_utc_datetime(),
0 ignored issues
show
Bug introduced by
It seems like api_get_utc_datetime() can also be of type object<DateTime>; however, Event::addEvent() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
155
            $user_id
156
        );
157
        echo Display::return_message(get_lang('SettingsStored'), 'confirmation');
158
    }
159
160
    $all_plugins = $plugin_obj->read_plugins_from_path();
161
    $installed_plugins = $plugin_obj->get_installed_plugins();
162
163
    // Plugins NOT installed
164
    echo Display::page_subheader(get_lang('Plugins'));
165
    echo '<form class="form-horizontal" name="plugins" method="post" action="'.api_get_self().'?category='.Security::remove_XSS($_GET['category']).'&sec_token='.$token.'">';
166
    echo '<table class="data_table">';
167
    /*echo '<tr>';
168
    echo '<th>';
169
    echo get_lang('Description');
170
    echo '</th>';
171
    echo '</tr>';*/
172
173
    foreach ($all_plugins as $pluginName) {
174
        $plugin_info_file = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/plugin.php';
175
        if (file_exists($plugin_info_file)) {
176
            $plugin_info = array();
177
            require $plugin_info_file;
178
179
            echo '<tr>';
180
            if (in_array($pluginName, $installed_plugins)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

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

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

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

could be turned into

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

This is much more concise to read.

Loading history...
181
            } else {
182
                if ($installed) {
183
                    continue;
184
                }
185
            }
186
187
            if ($installed == false) {
188
                if (in_array($pluginName, $installed_plugins)) {
189
                    continue;
190
                }
191
            }
192
193
            // Checkbox
194
            if (in_array($pluginName, $installed_plugins)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

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

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

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

could be turned into

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

This is much more concise to read.

Loading history...
195
                //echo '<input type="checkbox" name="plugin_'.$pluginName.'[]" checked="checked">';
196
            } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

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

These else branches can be removed.

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

could be turned into

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

This is much more concise to read.

Loading history...
197
                //echo '<input type="checkbox" name="plugin_'.$pluginName.'[]">';
198
            }
199
200
            echo '<td>';
201
            echo '<h4>'.$plugin_info['title'].' <small>v '.$plugin_info['version'].'</small></h4>';
202
            echo '<p>'.$plugin_info['comment'].'</p>';
203
            echo '<p>'.get_lang('Author').': '.$plugin_info['author'].'</p>';
204
            echo '<div class="btn-group">';
205
206
            $readme = '';
207
            if (file_exists(api_get_path(SYS_PLUGIN_PATH).$pluginName.'/readme.txt')) {
208
                $readme = Display::url(
209
                    "<em class='fa fa-file-text-o'></em> readme.txt",
210
                    api_get_path(WEB_PLUGIN_PATH).$pluginName."/readme.txt",
211
                    [
212
                        'class' => 'btn btn-default ajax',
213
                        'data-title' => $plugin_info['title'],
214
                        'data-size' => 'lg',
215
                        '_target' => '_blank'
216
                    ]
217
                );
218
            }
219
220
            $readmeFile = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/README.md';
221
            if (file_exists($readmeFile)) {
222
                $readme .= Display::url(
223
                    "<em class='fa fa-file-text-o'></em> README.md",
224
                    api_get_path(WEB_AJAX_PATH).'plugin.ajax.php?a=md_to_html&plugin='.$pluginName,
225
                    [
226
                        'class' => 'btn btn-default ajax',
227
                        'data-title' => $plugin_info['title'],
228
                        'data-size' => 'lg',
229
                        '_target' => '_blank'
230
                    ]
231
                );
232
            }
233
234
            if (in_array($pluginName, $installed_plugins)) {
235
                echo Display::url(
236
                    '<em class="fa fa-cogs"></em> '.get_lang('Configure'), 'configure_plugin.php?name='.$pluginName,
237
                    array('class' => 'btn btn-default')
238
                );
239
                echo Display::url(
240
                    '<em class="fa fa-th-large"></em> '.get_lang('Regions'), 'settings.php?category=Regions&name='.$pluginName,
241
                    array('class' => 'btn btn-default')
242
                );
243
244
                echo $readme;
245
246
                echo Display::url(
247
                    '<em class="fa trash-o fa-trash-o "></em> '.get_lang('Uninstall'), 'settings.php?category=Plugins&action=uninstall&name='.$pluginName,
248
                    array('class' => 'btn btn-danger')
249
                );
250
            } else {
251
                echo Display::url(
252
                    '<em class="fa fa-th-large"></em> '.get_lang('Install'), 'settings.php?category=Plugins&action=install&name='.$pluginName,
253
                    array('class' => 'btn btn-success')
254
                );
255
                echo $readme;
256
            }
257
            echo '</div>';
258
            echo '</td></tr>';
259
        }
260
    }
261
    echo '</table>';
262
263
    /*echo '<div class="form-actions bottom_actions">';
264
    echo '<button class="btn btn-success" type="submit" name="submit_plugins">'.
265
            get_lang('EnablePlugins').'</button>';
266
    echo '</div>';*/
267
    echo '</form>';
268
}
269
270
/**
271
 * This function allows the platform admin to choose the default stylesheet
272
 * @author Patrick Cool <[email protected]>, Ghent University
273
 * @author Julio Montoya <[email protected]>, Chamilo
274
 */
275
function handleStylesheets()
276
{
277
    $is_style_changeable = isStyleChangeable();
278
    $allowedFileTypes = ['png'];
279
280
    $form = new FormValidator(
281
        'stylesheet_upload',
282
        'post',
283
        'settings.php?category=Stylesheets#tabs-3'
284
    );
285
    $form->addElement(
286
        'text',
287
        'name_stylesheet',
288
        get_lang('NameStylesheet'),
289
        array('size' => '40', 'maxlength' => '40')
290
    );
291
    $form->addRule(
292
        'name_stylesheet',
293
        get_lang('ThisFieldIsRequired'),
294
        'required'
295
    );
296
    $form->addElement(
297
        'file',
298
        'new_stylesheet',
299
        get_lang('UploadNewStylesheet')
300
    );
301
    $allowed_file_types = getAllowedFileTypes();
302
303
    $form->addRule(
304
        'new_stylesheet',
305
        get_lang('InvalidExtension').' ('.implode(',', $allowed_file_types).')',
306
        'filetype',
307
        $allowed_file_types
308
    );
309
    $form->addRule(
310
        'new_stylesheet',
311
        get_lang('ThisFieldIsRequired'),
312
        'required'
313
    );
314
    $form->addButtonUpload(get_lang('Upload'), 'stylesheet_upload');
315
316
    $show_upload_form = false;
317
    $urlId = api_get_current_access_url_id();
318
319
    if (!is_writable(CSS_UPLOAD_PATH)) {
320
        echo Display::return_message(
321
            CSS_UPLOAD_PATH.get_lang('IsNotWritable'),
322
            'error',
323
            false
324
        );
325
    } else {
326
        // Uploading a new stylesheet.
327
        if ($urlId == 1) {
328
            $show_upload_form = true;
329
        } else {
330
            if ($is_style_changeable) {
331
                $show_upload_form = true;
332
            }
333
        }
334
    }
335
336
    // Stylesheet upload.
337
    if (isset($_POST['stylesheet_upload'])) {
338
        if ($form->validate()) {
339
            $values = $form->exportValues();
340
            $picture_element = $form->getElement('new_stylesheet');
341
            $picture = $picture_element->getValue();
342
            $result = uploadStylesheet($values, $picture);
343
344
            // Add event to the system log.
345
            $user_id = api_get_user_id();
346
            $category = $_GET['category'];
347
            Event::addEvent(
348
                LOG_CONFIGURATION_SETTINGS_CHANGE,
349
                LOG_CONFIGURATION_SETTINGS_CATEGORY,
350
                $category,
351
                api_get_utc_datetime(),
0 ignored issues
show
Bug introduced by
It seems like api_get_utc_datetime() can also be of type object<DateTime>; however, Event::addEvent() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
352
                $user_id
353
            );
354
355
            if ($result) {
356
                echo Display::return_message(get_lang('StylesheetAdded'));
357
            }
358
        }
359
    }
360
361
    // Current style.
362
    $selected = $currentStyle = api_get_setting('stylesheets');
363
    $styleFromDatabase = api_get_settings_params_simple(
364
        ['variable = ? AND access_url = ?' => ['stylesheets', api_get_current_access_url_id()]]
365
    );
366
    if ($styleFromDatabase) {
367
        $selected = $currentStyle = $styleFromDatabase['selected_value'];
368
    }
369
370
    if (isset($_POST['preview'])) {
371
        $selected = $currentStyle = Security::remove_XSS($_POST['style']);
372
    }
373
374
    $themeDir = Template::getThemeDir($selected);
375
    $dir = api_get_path(SYS_PUBLIC_PATH).'css/'.$themeDir.'/images/';
376
    $url = api_get_path(WEB_CSS_PATH).'/'.$themeDir.'/images/';
377
    $logoFileName = 'header-logo.png';
378
    $newLogoFileName = 'header-logo-custom'.api_get_current_access_url_id().'.png';
379
    $webPlatformLogoPath = ChamiloApi::getWebPlatformLogoPath($selected);
380
381
    $logoForm = new FormValidator(
382
        'logo_upload',
383
        'post',
384
        'settings.php?category=Stylesheets#tabs-2'
385
    );
386
387
    $logoForm->addHtml(
388
        Display::return_message(
389
            sprintf(
390
                get_lang('TheLogoMustBeSizeXAndFormatY'),
391
                '250 x 70',
392
                'PNG'
393
            ),
394
            'info'
395
        )
396
    );
397
398
    if ($webPlatformLogoPath !== null) {
399
        $logoForm->addLabel(
400
            get_lang('CurrentLogo'),
401
            '<img id="header-logo-custom" src="'.$webPlatformLogoPath.'?'.time().'">'
402
        );
403
    }
404
    $logoForm->addFile('new_logo', get_lang('UpdateLogo'));
405
    if ($is_style_changeable) {
406
        $logoGroup = [
407
            $logoForm->addButtonUpload(get_lang('Upload'), 'logo_upload', true),
408
            $logoForm->addButtonCancel(get_lang('Reset'), 'logo_reset', true)
409
        ];
410
411
        $logoForm->addGroup($logoGroup);
412
    }
413
414
    if (isset($_POST['logo_reset'])) {
415
        if (is_file($dir.$newLogoFileName)) {
416
            unlink($dir.$newLogoFileName);
417
            echo Display::return_message(get_lang('ResetToTheOriginalLogo'));
418
            echo '<script>'
419
                . '$("#header-logo").attr("src","'.$url.$logoFileName.'");'
420
            . '</script>';
421
        }
422
    } elseif (isset($_POST['logo_upload'])) {
423
        $logoForm->addRule('new_logo', get_lang('InvalidExtension').' ('.implode(',', $allowedFileTypes).')', 'filetype', $allowedFileTypes);
424
        $logoForm->addRule('new_logo', get_lang('ThisFieldIsRequired'), 'required');
425
426
        if ($logoForm->validate()) {
427
            $imageInfo = getimagesize($_FILES['new_logo']['tmp_name']);
428
            $width = $imageInfo[0];
429
            $height = $imageInfo[1];
430
            if ($width <= 250 && $height <= 70) {
431
                if (is_file($dir.$newLogoFileName)) {
432
                    unlink($dir.$newLogoFileName);
433
                }
434
435
                $status = move_uploaded_file($_FILES['new_logo']['tmp_name'], $dir.$newLogoFileName);
436
437
                if ($status) {
438
                    echo Display::return_message(get_lang('NewLogoUpdated'));
439
                    echo '<script>'
440
                            . '$("#header-logo").attr("src","'.$url.$newLogoFileName.'");'
441
                        . '</script>';
442
                } else {
443
                    echo Display::return_message('Error - '.get_lang('UplNoFileUploaded'), 'error');
444
                }
445
            } else {
446
                Display::return_message('Error - '.get_lang('InvalidImageDimensions'), 'error');
447
            }
448
        }
449
    }
450
451
    if (isset($_POST['download'])) {
452
        generateCSSDownloadLink($selected);
453
    }
454
455
    $form_change = new FormValidator(
456
        'stylesheet_upload',
457
        'post',
458
        api_get_self().'?category=Stylesheets',
459
        null,
460
        array('id' => 'stylesheets_id')
461
    );
462
463
    $styles = $form_change->addElement(
464
        'selectTheme',
465
        'style',
466
        get_lang('NameStylesheet')
467
    );
468
    $styles->setSelected($currentStyle);
469
470
    if ($is_style_changeable) {
471
        $group = [
472
            $form_change->addButtonSave(get_lang('SaveSettings'), 'save', true),
473
            $form_change->addButtonPreview(get_lang('Preview'), 'preview', true),
474
            $form_change->addButtonDownload(get_lang('Download'), 'download', true)
475
        ];
476
477
        $form_change->addGroup($group);
478
479
        if ($show_upload_form) {
480
            echo Display::tabs(
481
                array(get_lang('Update'), get_lang('UpdateLogo'), get_lang('UploadNewStylesheet')),
482
                array($form_change->returnForm(), $logoForm->returnForm(), $form->returnForm())
483
            );
484
        } else {
485
            $form_change->display();
486
        }
487
488
        // Little hack to update the logo image in update form when submiting
489
        if (isset($_POST['logo_reset'])) {
490
            echo '<script>'
491
                    . '$("#header-logo-custom").attr("src","'.$url.$logoFileName.'");'
492
                . '</script>';
493
        } elseif (isset($_POST['logo_upload']) && is_file($dir.$newLogoFileName)) {
494
            echo '<script>'
495
                    . '$("#header-logo-custom").attr("src","'.$url.$newLogoFileName.'");'
496
                . '</script>';
497
        }
498
    } else {
499
        $form_change->freeze();
500
    }
501
}
502
503
/**
504
 * Creates the folder (if needed) and uploads the stylesheet in it
505
 * @param array $values the values of the form
506
 * @param array $picture the values of the uploaded file
507
 * @return bool
508
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
509
 * @version May 2008
510
 * @since v1.8.5
511
 */
512
function uploadStylesheet($values, $picture)
513
{
514
    $result = false;
515
    // Valid name for the stylesheet folder.
516
    $style_name = api_preg_replace('/[^A-Za-z0-9]/', '', $values['name_stylesheet']);
517
    $cssToUpload = CSS_UPLOAD_PATH;
518
519
    // Check if a virtual instance vchamilo is used
520
    $virtualInstanceTheme = api_get_configuration_value('virtual_css_theme_folder');
521
    if (!empty($virtualInstanceTheme)) {
522
        $cssToUpload = $cssToUpload.$virtualInstanceTheme.'/';
523
    }
524
525
    // Create the folder if needed.
526
    if (!is_dir($cssToUpload.$style_name.'/')) {
527
        mkdir($cssToUpload.$style_name.'/', api_get_permissions_for_new_directories());
528
    }
529
530
    $info = pathinfo($picture['name']);
531
532
    if ($info['extension'] == 'zip') {
533
        // Try to open the file and extract it in the theme.
534
        $zip = new ZipArchive();
535
        if ($zip->open($picture['tmp_name'])) {
536
            // Make sure all files inside the zip are images or css.
537
            $num_files = $zip->numFiles;
538
            $valid = true;
539
            $single_directory = true;
540
            $invalid_files = array();
541
542
            $allowedFiles = getAllowedFileTypes();
543
544
            for ($i = 0; $i < $num_files; $i++) {
545
                $file = $zip->statIndex($i);
546
                if (substr($file['name'], -1) != '/') {
547
                    $path_parts = pathinfo($file['name']);
548
                    if (!in_array($path_parts['extension'], $allowedFiles)) {
549
                        $valid = false;
550
                        $invalid_files[] = $file['name'];
551
                    }
552
                }
553
554
                if (strpos($file['name'], '/') === false) {
555
                    $single_directory = false;
556
                }
557
            }
558
            if (!$valid) {
559
                $error_string = '<ul>';
560
                foreach ($invalid_files as $invalid_file) {
561
                    $error_string .= '<li>'.$invalid_file.'</li>';
562
                }
563
                $error_string .= '</ul>';
564
                echo Display::return_message(
565
                    get_lang('ErrorStylesheetFilesExtensionsInsideZip').$error_string,
566
                    'error',
567
                    false
568
                );
569
            } else {
570
                // If the zip does not contain a single directory, extract it.
571
                if (!$single_directory) {
572
                    // Extract zip file.
573
                    $zip->extractTo($cssToUpload.$style_name.'/');
574
                    $result = true;
575
                } else {
576
                    $extraction_path = $cssToUpload.$style_name.'/';
577
                    for ($i = 0; $i < $num_files; $i++) {
578
                        $entry = $zip->getNameIndex($i);
579
                        if (substr($entry, -1) == '/') {
580
                            continue;
581
                        }
582
583
                        $pos_slash = strpos($entry, '/');
584
                        $entry_without_first_dir = substr($entry, $pos_slash + 1);
585
                        // If there is still a slash, we need to make sure the directories are created.
586
                        if (strpos($entry_without_first_dir, '/') !== false) {
587
                            if (!is_dir($extraction_path.dirname($entry_without_first_dir))) {
588
                                // Create it.
589
                                @mkdir($extraction_path.dirname($entry_without_first_dir), $mode = 0777, true);
590
                            }
591
                        }
592
593
                        $fp = $zip->getStream($entry);
594
                        $ofp = fopen($extraction_path.dirname($entry_without_first_dir).'/'.basename($entry), 'w');
595
596
                        while (!feof($fp)) {
597
                            fwrite($ofp, fread($fp, 8192));
598
                        }
599
600
                        fclose($fp);
601
                        fclose($ofp);
602
                    }
603
                    $result = true;
604
                }
605
            }
606
            $zip->close();
607
        } else {
608
            echo Display::return_message(get_lang('ErrorReadingZip').$info['extension'], 'error', false);
609
        }
610
    } else {
611
        // Simply move the file.
612
        move_uploaded_file($picture['tmp_name'], $cssToUpload.$style_name.'/'.$picture['name']);
613
        $result = true;
614
    }
615
616
    if ($result) {
617
        $fs = new Filesystem();
618
        $fs->mirror(
619
            CSS_UPLOAD_PATH,
620
            api_get_path(SYS_PATH).'web/css/themes/',
621
            null,
622
            ['override' => true]
623
        );
624
    }
625
626
    return $result;
627
}
628
629
/**
630
 * Store plugin regions.
631
 */
632
function storeRegions()
633
{
634
    $plugin_obj = new AppPlugin();
635
636
    // Get a list of all current 'Plugins' settings
637
    $installed_plugins = $plugin_obj->get_installed_plugins();
638
    $shortlist_installed = array();
639
    if (!empty($installed_plugins)) {
640
        foreach ($installed_plugins as $plugin) {
641
            if (isset($plugin['subkey'])) {
642
                $shortlist_installed[] = $plugin['subkey'];
643
            }
644
        }
645
    }
646
647
    $plugin_list = $plugin_obj->read_plugins_from_path();
648
649
    foreach ($plugin_list as $plugin) {
650
        if (isset($_POST['plugin_'.$plugin])) {
651
            $areas_to_installed = $_POST['plugin_'.$plugin];
652
            if (!empty($areas_to_installed)) {
653
                $plugin_obj->remove_all_regions($plugin);
654
                foreach ($areas_to_installed as $region) {
655
                    if (!empty($region) && $region != '-1') {
656
                        $plugin_obj->add_to_region($plugin, $region);
657
                    }
658
                }
659
            }
660
        }
661
    }
662
}
663
664
/**
665
 * This function allows easy activating and inactivating of plugins
666
 * @author Patrick Cool <[email protected]>, Ghent University
667
 */
668
function storePlugins()
669
{
670
    $appPlugin = new AppPlugin();
671
672
    // Get a list of all current 'Plugins' settings
673
    $plugin_list = $appPlugin->read_plugins_from_path();
674
675
    var_dump($plugin_list);exit;
0 ignored issues
show
Security Debugging Code introduced by
var_dump($plugin_list); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
676
    $installed_plugins = array();
0 ignored issues
show
Unused Code introduced by
$installed_plugins = array(); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
677
678
    foreach ($plugin_list as $plugin) {
679
        if (isset($_POST['plugin_'.$plugin])) {
680
            $appPlugin->install($plugin);
681
            $installed_plugins[] = $plugin;
682
        }
683
    }
684
685
    if (!empty($installed_plugins)) {
686
        $remove_plugins = array_diff($plugin_list, $installed_plugins);
687
    } else {
688
        $remove_plugins = $plugin_list;
689
    }
690
691
    /*foreach ($remove_plugins as $plugin) {
692
        $appPlugin->uninstall($plugin);
693
    }*/
694
}
695
696
/**
697
 * This function allows the platform admin to choose which should be the default stylesheet
698
 * @author Patrick Cool <[email protected]>, Ghent University
699
 */
700
function storeStylesheets()
701
{
702
    // Insert the stylesheet.
703
    if (isStyle($_POST['style'])) {
704
        api_set_setting(
705
            'stylesheets',
706
            $_POST['style'],
707
            null,
708
            'stylesheets',
709
            api_get_current_access_url_id()
710
        );
711
    }
712
    return true;
713
}
714
715
/**
716
 * This function checks if the given style is a recognize style that exists in the css directory as
717
 * a standalone directory.
718
 * @param string $style
719
 * @return bool     True if this style is recognized, false otherwise
720
 */
721
function isStyle($style)
722
{
723
    $themeList = api_get_themes();
724
725
    return in_array($style, array_keys($themeList));
726
}
727
728
/**
729
 * Search options
730
 * TODO: support for multiple site. aka $_configuration['access_url'] == 1
731
 * @author Marco Villegas <[email protected]>
732
 */
733
function handleSearch()
734
{
735
    global $SettingsStored, $_configuration;
736
737
    require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
738
    $search_enabled = api_get_setting('search_enabled');
739
740
    $form = new FormValidator('search-options', 'post', api_get_self().'?category=Search');
741
    $values = api_get_settings_options('search_enabled');
742
    $form->addElement('header', null, get_lang('SearchEnabledTitle'));
743
744
    $group = formGenerateElementsGroup($form, $values, 'search_enabled');
745
746
    //SearchEnabledComment
747
    $form->addGroup($group, 'search_enabled', array(get_lang('SearchEnabledTitle'), get_lang('SearchEnabledComment')), null, false);
748
749
    $search_enabled = api_get_setting('search_enabled');
750
751
    if ($form->validate()) {
752
        $formValues = $form->exportValues();
753
        setConfigurationSettingsInDatabase($formValues, $_configuration['access_url']);
754
        $search_enabled = $formValues['search_enabled'];
755
        echo Display::return_message($SettingsStored, 'confirm');
756
    }
757
    $specific_fields = get_specific_field_list();
758
759
    if ($search_enabled == 'true') {
760
        $values = api_get_settings_options('search_show_unlinked_results');
761
762
        $group = formGenerateElementsGroup($form, $values, 'search_show_unlinked_results');
763
        $form->addGroup($group, 'search_show_unlinked_results', array(get_lang('SearchShowUnlinkedResultsTitle'), get_lang('SearchShowUnlinkedResultsComment')), null, false);
764
        $default_values['search_show_unlinked_results'] = api_get_setting('search_show_unlinked_results');
765
766
        $sf_values = array();
767
        foreach ($specific_fields as $sf) {
768
            $sf_values[$sf['code']] = $sf['name'];
769
        }
770
        $url = Display::div(Display::url(get_lang('AddSpecificSearchField'), 'specific_fields.php'), array('class'=>'sectioncomment'));
771
        if (empty($sf_values)) {
772
            $form->addElement('label', [get_lang('SearchPrefilterPrefix'), $url]);
773
        } else {
774
            $form->addElement('select', 'search_prefilter_prefix', array(get_lang('SearchPrefilterPrefix'), $url), $sf_values, '');
775
            $default_values['search_prefilter_prefix'] = api_get_setting('search_prefilter_prefix');
776
        }
777
    }
778
779
    $default_values['search_enabled'] = $search_enabled;
780
781
    $form->addButtonSave(get_lang('Save'));
782
    $form->setDefaults($default_values);
783
784
    echo '<div id="search-options-form">';
785
    $form->display();
786
    echo '</div>';
787
788
    if ($search_enabled == 'true') {
789
        $xapianPath = api_get_path(SYS_UPLOAD_PATH).'plugins/xapian/searchdb';
790
791
        /*
792
        @todo Test the Xapian connection
793
        if (extension_loaded('xapian')) {
794
            require_once 'xapian.php';
795
            try {
796
                $db = new XapianDatabase($xapianPath.'/');
797
            } catch (Exception $e) {
798
                var_dump($e->getMessage());
799
            }
800
801
            require_once api_get_path(LIBRARY_PATH) . 'search/ChamiloIndexer.class.php';
802
            require_once api_get_path(LIBRARY_PATH) . 'search/IndexableChunk.class.php';
803
            require_once api_get_path(LIBRARY_PATH) . 'specific_fields_manager.lib.php';
804
805
            $indexable = new IndexableChunk();
806
            $indexable->addValue("content", 'Test');
807
808
            $di = new ChamiloIndexer();
809
            $di->connectDb(NULL, NULL, 'english');
810
            $di->addChunk($indexable);
811
            $did = $di->index();
812
        }
813
        */
814
815
        $xapianLoaded = Display::return_icon('bullet_green.png', get_lang('Ok'));
816
        $dir_exists = Display::return_icon('bullet_green.png', get_lang('Ok'));
817
        $dir_is_writable = Display::return_icon('bullet_green.png', get_lang('Ok'));
818
        $specific_fields_exists = Display::return_icon('bullet_green.png', get_lang('Ok'));
819
820
        //Testing specific fields
821
        if (empty($specific_fields)) {
822
            $specific_fields_exists = Display::return_icon('bullet_red.png', get_lang('AddSpecificSearchField'));
823
        }
824
        //Testing xapian extension
825
        if (!extension_loaded('xapian')) {
826
            $xapianLoaded = Display::return_icon('bullet_red.png', get_lang('Error'));
827
        }
828
        //Testing xapian searchdb path
829
        if (!is_dir($xapianPath)) {
830
            $dir_exists = Display::return_icon('bullet_red.png', get_lang('Error'));
831
        }
832
        //Testing xapian searchdb path is writable
833
        if (!is_writable($xapianPath)) {
834
            $dir_is_writable = Display::return_icon('bullet_red.png', get_lang('Error'));
835
        }
836
837
        $data = array();
838
        $data[] = array(get_lang('XapianModuleInstalled'), $xapianLoaded);
839
        $data[] = array(get_lang('DirectoryExists').' - '.$xapianPath, $dir_exists);
840
        $data[] = array(get_lang('IsWritable').' - '.$xapianPath, $dir_is_writable);
841
        $data[] = array(get_lang('SpecificSearchFieldsAvailable'), $specific_fields_exists);
842
843
        showSearchSettingsTable($data);
844
        showSearchToolsStatusTable();
845
    }
846
}
847
848
/**
849
 * Wrapper for the templates
850
 *
851
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
852
 * @author Julio Montoya.
853
 * @version August 2008
854
 * @since v1.8.6
855
 */
856
function handleTemplates()
857
{
858
    /* Drive-by fix to avoid undefined var warnings, without repeating
859
     * isset() combos all over the place. */
860
    $action = isset($_GET['action']) ? $_GET['action'] : "invalid";
861
862
    if ($action != 'add') {
863
        echo '<div class="actions" style="margin-left: 1px;">';
864
        echo '<a href="settings.php?category=Templates&action=add">'.
865
                Display::return_icon('new_template.png', get_lang('AddTemplate'), '', ICON_SIZE_MEDIUM).'</a>';
866
        echo '</div>';
867
    }
868
869
    if ($action == 'add' || ($action == 'edit' && is_numeric($_GET['id']))) {
870
        addEditTemplate();
871
872
        // Add event to the system log.
873
        $user_id = api_get_user_id();
874
        $category = $_GET['category'];
875
        Event::addEvent(
876
            LOG_CONFIGURATION_SETTINGS_CHANGE,
877
            LOG_CONFIGURATION_SETTINGS_CATEGORY,
878
            $category,
879
            api_get_utc_datetime(),
0 ignored issues
show
Bug introduced by
It seems like api_get_utc_datetime() can also be of type object<DateTime>; however, Event::addEvent() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
880
            $user_id
881
        );
882
    } else {
883
        if ($action == 'delete' && is_numeric($_GET['id'])) {
884
            deleteTemplate($_GET['id']);
885
886
            // Add event to the system log
887
            $user_id = api_get_user_id();
888
            $category = $_GET['category'];
889
            Event::addEvent(
890
                LOG_CONFIGURATION_SETTINGS_CHANGE,
891
                LOG_CONFIGURATION_SETTINGS_CATEGORY,
892
                $category,
893
                api_get_utc_datetime(),
0 ignored issues
show
Bug introduced by
It seems like api_get_utc_datetime() can also be of type object<DateTime>; however, Event::addEvent() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
894
                $user_id
895
            );
896
        }
897
        displayTemplates();
898
    }
899
}
900
901
/**
902
 * Display a sortable table with all the templates that the platform administrator has defined.
903
 *
904
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
905
 * @version August 2008
906
 * @since v1.8.6
907
 */
908
function displayTemplates()
909
{
910
    $table = new SortableTable('templates', 'getNumberOfTemplates', 'getTemplateData', 1);
911
    $table->set_additional_parameters(array('category' => Security::remove_XSS($_GET['category'])));
912
    $table->set_header(0, get_lang('Image'), true, array('style' => 'width: 101px;'));
913
    $table->set_header(1, get_lang('Title'));
914
    $table->set_header(2, get_lang('Actions'), false, array('style' => 'width:50px;'));
915
    $table->set_column_filter(2, 'actionsFilter');
916
    $table->set_column_filter(0, 'searchImageFilter');
917
    $table->display();
918
}
919
920
/**
921
 * Gets the number of templates that are defined by the platform admin.
922
 *
923
 * @return integer
924
 *
925
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
926
 * @version August 2008
927
 * @since v1.8.6
928
 */
929 View Code Duplication
function getNumberOfTemplates()
930
{
931
    // Database table definition.
932
    $table_system_template = Database::get_main_table('system_template');
933
934
    // The sql statement.
935
    $sql = "SELECT COUNT(id) AS total FROM $table_system_template";
936
    $result = Database::query($sql);
937
    $row = Database::fetch_array($result);
938
939
    // Returning the number of templates.
940
    return $row['total'];
941
}
942
943
/**
944
 * Gets all the template data for the sortable table.
945
 *
946
 * @param integer $from the start of the limit statement
947
 * @param integer $number_of_items the number of elements that have to be retrieved from the database
948
 * @param integer $column the column that is
949
 * @param string $direction the sorting direction (ASC or DESC�
950
 * @return array
951
 *
952
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
953
 * @version August 2008
954
 * @since v1.8.6
955
 */
956
function getTemplateData($from, $number_of_items, $column, $direction)
957
{
958
    // Database table definition.
959
    $table_system_template = Database::get_main_table('system_template');
960
961
    // The sql statement.
962
    $sql = "SELECT image as col0, title as col1, id as col2 FROM $table_system_template";
963
    $sql .= " ORDER BY col$column $direction ";
964
    $sql .= " LIMIT $from,$number_of_items";
965
    $result = Database::query($sql);
966
    $return = array();
967
    while ($row = Database::fetch_array($result)) {
968
        $row['1'] = get_lang($row['1']);
969
        $return[] = $row;
970
    }
971
    // Returning all the information for the sortable table.
972
    return $return;
973
}
974
975
/**
976
 * display the edit and delete icons in the sortable table
977
 *
978
 * @param integer $id the id of the template
979
 * @return string code for the link to edit and delete the template
980
 *
981
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
982
 * @version August 2008
983
 * @since v1.8.6
984
 */
985
function actionsFilter($id) {
986
    $return = '<a href="settings.php?category=Templates&action=edit&id='.Security::remove_XSS($id).'">'.Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_SMALL).'</a>';
987
    $return .= '<a href="settings.php?category=Templates&action=delete&id='.Security::remove_XSS($id).'" onClick="javascript:if(!confirm('."'".get_lang('ConfirmYourChoice')."'".')) return false;">'.Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL).'</a>';
988
    return $return;
989
}
990
991
/**
992
 * Display the image of the template in the sortable table
993
 *
994
 * @param string $image the image
995
 * @return string code for the image
996
 *
997
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
998
 * @version August 2008
999
 * @since v1.8.6
1000
 */
1001
function searchImageFilter($image)
1002
{
1003
    if (!empty($image)) {
1004
        return '<img src="'.api_get_path(WEB_APP_PATH).'home/default_platform_document/template_thumb/'.$image.'" alt="'.get_lang('TemplatePreview').'"/>';
1005
    } else {
1006
        return '<img src="'.api_get_path(WEB_APP_PATH).'home/default_platform_document/template_thumb/noimage.gif" alt="'.get_lang('NoTemplatePreview').'"/>';
1007
    }
1008
}
1009
1010
/**
1011
 * Add (or edit) a template. This function displays the form and also takes
1012
 * care of uploading the image and storing the information in the database
1013
 *
1014
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
1015
 * @version August 2008
1016
 * @since v1.8.6
1017
 */
1018
function addEditTemplate()
1019
{
1020
    // Initialize the object.
1021
    $id = isset($_GET['id']) ? '&id='.Security::remove_XSS($_GET['id']) : '';
1022
    $form = new FormValidator('template', 'post', 'settings.php?category=Templates&action='.Security::remove_XSS($_GET['action']).$id);
1023
1024
    // Setting the form elements: the header.
1025
    if ($_GET['action'] == 'add') {
1026
        $title = get_lang('AddTemplate');
1027
    } else {
1028
        $title = get_lang('EditTemplate');
1029
    }
1030
    $form->addElement('header', '', $title);
1031
1032
    // Setting the form elements: the title of the template.
1033
    $form->addText('title', get_lang('Title'), false);
1034
1035
    // Setting the form elements: the content of the template (wysiwyg editor).
1036
    $form->addElement('html_editor', 'template_text', get_lang('Text'), null, array('ToolbarSet' => 'AdminTemplates', 'Width' => '100%', 'Height' => '400'));
1037
1038
    // Setting the form elements: the form to upload an image to be used with the template.
1039
    $form->addElement('file', 'template_image', get_lang('Image'), '');
1040
1041
    // Setting the form elements: a little bit information about the template image.
1042
    $form->addElement('static', 'file_comment', '', get_lang('TemplateImageComment100x70'));
1043
1044
    // Getting all the information of the template when editing a template.
1045
    if ($_GET['action'] == 'edit') {
1046
        // Database table definition.
1047
        $table_system_template = Database::get_main_table('system_template');
1048
        $sql = "SELECT * FROM $table_system_template WHERE id = ".intval($_GET['id'])."";
1049
        $result = Database::query($sql);
1050
        $row = Database::fetch_array($result);
1051
1052
        $defaults['template_id'] = intval($_GET['id']);
1053
        $defaults['template_text'] = $row['content'];
1054
        // Forcing get_lang().
1055
        $defaults['title'] = get_lang($row['title']);
1056
1057
        // Adding an extra field: a hidden field with the id of the template we are editing.
1058
        $form->addElement('hidden', 'template_id');
1059
1060
        // Adding an extra field: a preview of the image that is currently used.
1061
        if (!empty($row['image'])) {
1062
            $form->addElement('static', 'template_image_preview', '',
1063
                '<img src="'.api_get_path(WEB_APP_PATH).'home/default_platform_document/template_thumb/'.$row['image'].'" alt="'.get_lang('TemplatePreview').'"/>');
1064
        } else {
1065
            $form->addElement('static', 'template_image_preview', '',
1066
                '<img src="'.api_get_path(WEB_APP_PATH).'home/default_platform_document/template_thumb/noimage.gif" alt="'.get_lang('NoTemplatePreview').'"/>');
1067
        }
1068
1069
        // Setting the information of the template that we are editing.
1070
        $form->setDefaults($defaults);
1071
    }
1072
    // Setting the form elements: the submit button.
1073
    $form->addButtonSave(get_lang('Ok'), 'submit');
1074
1075
    // Setting the rules: the required fields.
1076
    $form->addRule('template_image', get_lang('ThisFieldIsRequired'), 'required');
1077
    $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
1078
    $form->addRule('template_text', get_lang('ThisFieldIsRequired'), 'required');
1079
1080
    // if the form validates (complies to all rules) we save the information, else we display the form again (with error message if needed)
1081
    if ($form->validate()) {
1082
        $check = Security::check_token('post');
1083
        if ($check) {
1084
            // Exporting the values.
1085
            $values = $form->exportValues();
1086
            // Upload the file.
1087
            if (!empty($_FILES['template_image']['name'])) {
1088
                $upload_ok = process_uploaded_file($_FILES['template_image']);
1089
1090
                if ($upload_ok) {
1091
                    // Try to add an extension to the file if it hasn't one.
1092
                    $new_file_name = add_ext_on_mime(stripslashes($_FILES['template_image']['name']), $_FILES['template_image']['type']);
1093
1094
                    // The upload directory.
1095
                    $upload_dir = api_get_path(SYS_APP_PATH).'home/default_platform_document/template_thumb/';
1096
1097
                    // Create the directory if it does not exist.
1098
                    if (!is_dir($upload_dir)) {
1099
                        mkdir($upload_dir, api_get_permissions_for_new_directories());
1100
                    }
1101
1102
                    // Resize the preview image to max default and upload.
1103
                    $temp = new Image($_FILES['template_image']['tmp_name']);
1104
                    $picture_info = $temp->get_image_info();
1105
1106
                    $max_width_for_picture = 100;
1107
1108
                    if ($picture_info['width'] > $max_width_for_picture) {
1109
                        $temp->resize($max_width_for_picture);
1110
                    }
1111
                    $temp->send_image($upload_dir.$new_file_name);
1112
                }
1113
            }
1114
1115
            // Store the information in the database (as insert or as update).
1116
            $table_system_template = Database::get_main_table('system_template');
1117
            if ($_GET['action'] == 'add') {
1118
                $content_template = Security::remove_XSS($values['template_text'], COURSEMANAGERLOWSECURITY);
1119
                $params = [
1120
                    'title' =>  $values['title'],
1121
                    'content' => $content_template,
1122
                    'image' => $new_file_name
1123
                ];
1124
                Database::insert($table_system_template, $params);
1125
1126
                // Display a feedback message.
1127
                echo Display::return_message(get_lang('TemplateAdded'), 'confirm');
1128
                echo '<a href="settings.php?category=Templates&action=add">'.Display::return_icon('new_template.png', get_lang('AddTemplate'), '', ICON_SIZE_MEDIUM).'</a>';
1129
            } else {
1130
                $content_template = '<head>{CSS}<style type="text/css">.text{font-weight: normal;}</style></head><body>'.Database::escape_string($values['template_text']).'</body>';
1131
                $sql = "UPDATE $table_system_template set title = '".Database::escape_string($values['title'])."', content = '".$content_template."'";
1132
                if (!empty($new_file_name)) {
1133
                    $sql .= ", image = '".Database::escape_string($new_file_name)."'";
1134
                }
1135
                $sql .= " WHERE id = ".intval($_GET['id'])."";
1136
                Database::query($sql);
1137
1138
                // Display a feedback message.
1139
                echo Display::return_message(get_lang('TemplateEdited'), 'confirm');
1140
            }
1141
        }
1142
        Security::clear_token();
1143
        displayTemplates();
1144
    } else {
1145
        $token = Security::get_token();
1146
        $form->addElement('hidden', 'sec_token');
1147
        $form->setConstants(array('sec_token' => $token));
1148
        // Display the form.
1149
        $form->display();
1150
    }
1151
}
1152
1153
/**
1154
 * Delete a template
1155
 *
1156
 * @param integer $id the id of the template that has to be deleted
1157
 *
1158
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
1159
 * @version August 2008
1160
 * @since v1.8.6
1161
 */
1162
function deleteTemplate($id)
1163
{
1164
    // First we remove the image.
1165
    $table_system_template = Database::get_main_table('system_template');
1166
    $sql = "SELECT * FROM $table_system_template WHERE id = ".intval($id)."";
1167
    $result = Database::query($sql);
1168
    $row = Database::fetch_array($result);
1169
    if (!empty($row['image'])) {
1170
        @unlink(api_get_path(SYS_APP_PATH).'home/default_platform_document/template_thumb/'.$row['image']);
1171
    }
1172
1173
    // Now we remove it from the database.
1174
    $sql = "DELETE FROM $table_system_template WHERE id = ".intval($id)."";
1175
    Database::query($sql);
1176
1177
    // Display a feedback message.
1178
    echo Display::return_message(get_lang('TemplateDeleted'), 'confirm');
1179
}
1180
1181
/**
1182
 * Returns the list of timezone identifiers used to populate the select
1183
 * This function is called through a call_user_func() in the generate_settings_form function.
1184
 * @return array List of timezone identifiers
1185
 *
1186
 * @author Guillaume Viguier <[email protected]>
1187
 * @since Chamilo 1.8.7
1188
 */
1189
function select_timezone_value()
1190
{
1191
    return api_get_timezones();
1192
}
1193
1194
/**
1195
 * Returns an array containing the list of options used to populate the gradebook_number_decimals variable
1196
 * This function is called through a call_user_func() in the generate_settings_form function.
1197
 * @return array List of gradebook_number_decimals options
1198
 *
1199
 * @author Guillaume Viguier <[email protected]>
1200
 */
1201
function select_gradebook_number_decimals() {
1202
    return array('0', '1', '2');
1203
}
1204
1205
/**
1206
 * Get the options for a select element to select gradebook default grade model
1207
 * @return array
1208
 */
1209
function select_gradebook_default_grade_model_id()
1210
{
1211
    $grade_model = new GradeModel();
1212
    $models = $grade_model->get_all();
1213
    $options = array();
1214
    $options[-1] = get_lang('None');
1215
1216
    if (!empty($models)) {
1217
        foreach ($models as $model) {
1218
            $options[$model['id']] = $model['name'];
1219
        }
1220
    }
1221
1222
    return $options;
1223
}
1224
1225
/**
1226
 * @param array $settings
1227
 * @param array $settings_by_access_list
1228
 *
1229
 * @return FormValidator
1230
 *
1231
 * @throws \Doctrine\ORM\ORMException
1232
 * @throws \Doctrine\ORM\OptimisticLockException
1233
 * @throws \Doctrine\ORM\TransactionRequiredException
1234
 */
1235
function generateSettingsForm($settings, $settings_by_access_list)
1236
{
1237
    return;
1238
    global $_configuration, $settings_to_avoid, $convert_byte_to_mega_list;
0 ignored issues
show
Unused Code introduced by
global $_configuration, ...vert_byte_to_mega_list; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
1239
    $multipleAccessUrl = api_get_configuration_value('multiple_access_urls');
1240
    $em = Database::getManager();
1241
    $table_settings_current = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
1242
1243
    $form = new FormValidator('settings', 'post', 'settings.php?category='.Security::remove_XSS($_GET['category']));
1244
1245
    $form->addElement(
1246
        'hidden',
1247
        'search_field',
1248
        (!empty($_GET['search_field']) ? Security::remove_XSS($_GET['search_field']) : null)
1249
    );
1250
1251
    $url_id = api_get_current_access_url_id();
1252
    /*
1253
    if (!empty($_configuration['multiple_access_urls']) && api_is_global_platform_admin() && $url_id == 1) {
1254
        $group = array();
1255
        $group[] = $form->createElement('button', 'mark_all', get_lang('MarkAll'));
1256
        $group[] = $form->createElement('button', 'unmark_all', get_lang('UnmarkAll'));
1257
        $form->addGroup($group, 'buttons_in_action_right');
1258
    }*/
1259
1260
    $default_values = array();
1261
    $url_info = api_get_access_url($url_id);
1262
    $i = 0;
1263
    $addedSettings = [];
1264
    foreach ($settings as $row) {
1265
1266
        if (!empty($row['variable']) &&
1267
            in_array($row['variable'], array_keys($settings_to_avoid))
1268
        ) {
1269
            continue;
1270
        }
1271
1272
        if (!empty($row['variable']) &&
1273
            in_array($row['variable'], $addedSettings)
1274
        ) {
1275
            continue;
1276
        }
1277
1278
        $addedSettings[] = $row['variable'];
1279
1280
        if (!empty($multipleAccessUrl)) {
1281
            if (api_is_global_platform_admin()) {
1282
                if ($row['access_url_locked'] == 0) {
1283
                    if ($url_id == 1) {
1284
                        if ($row['access_url_changeable'] == '1') {
1285
                            $form->addElement(
1286
                                'html',
1287
                                '<div class="pull-right"><a class="share_this_setting" data_status = "0"  data_to_send = "'.$row['variable'].'" href="javascript:void(0);">'.
1288
                                Display::return_icon('shared_setting.png', get_lang('ChangeSharedSetting'), null, ICON_SIZE_MEDIUM).'</a></div>'
1289
                            );
1290
                        } else {
1291
                            $form->addElement(
1292
                                'html',
1293
                                '<div class="pull-right"><a class="share_this_setting" data_status = "1" data_to_send = "'.$row['variable'].'" href="javascript:void(0);">'.
1294
                                Display::return_icon('shared_setting_na.png', get_lang('ChangeSharedSetting'), null, ICON_SIZE_MEDIUM).'</a></div>'
1295
                            );
1296
                        }
1297
                    } else {
1298
                        if ($row['access_url_changeable'] == '1') {
1299
                            $form->addElement(
1300
                                'html',
1301
                                '<div class="pull-right">'.
1302
                                Display::return_icon('shared_setting.png', get_lang('ChangeSharedSetting'), null, ICON_SIZE_MEDIUM).'</div>'
1303
                            );
1304
                        } else {
1305
                            $form->addElement(
1306
                                'html',
1307
                                '<div class="pull-right">'.
1308
                                Display::return_icon('shared_setting_na.png', get_lang('ChangeSharedSetting'), null, ICON_SIZE_MEDIUM).'</div>'
1309
                            );
1310
                        }
1311
                    }
1312
                }
1313
            }
1314
        }
1315
1316
        $hideme = array();
1317
        $hide_element = false;
1318
1319
        if ($_configuration['access_url'] != 1) {
1320
            if ($row['access_url_changeable'] == 0) {
1321
                // We hide the element in other cases (checkbox, radiobutton) we 'freeze' the element.
1322
                $hide_element = true;
1323
                $hideme = array('disabled');
1324
            } elseif ($url_info['active'] == 1) {
1325
                // We show the elements.
1326
                if (empty($row['variable'])) {
1327
                    $row['variable'] = 0;
1328
                }
1329
                if (empty($row['subkey'])) {
1330
                    $row['subkey'] = 0;
1331
                }
1332
                if (empty($row['category'])) {
1333
                    $row['category'] = 0;
1334
                }
1335
                if (isset($settings_by_access_list[$row['variable']]) &&
1336
                    is_array($settings_by_access_list[$row['variable']][$row['subkey']][$row['category']])) {
1337
                    // We are sure that the other site have a selected value.
1338
                    if ($settings_by_access_list[$row['variable']][$row['subkey']][$row['category']]['selected_value'] != '') {
1339
                        $row['selected_value'] = $settings_by_access_list[$row['variable']][$row['subkey']][$row['category']]['selected_value'];
1340
                    }
1341
                }
1342
                // There is no else{} statement because we load the default $row['selected_value'] of the main Chamilo site.
1343
            }
1344
        }
1345
1346
        switch ($row['type']) {
1347
            case 'textfield':
1348
                if (in_array($row['variable'], $convert_byte_to_mega_list)) {
1349
                    $form->addElement(
1350
                        'text',
1351
                        $row['variable'],
1352
                        array(
1353
                            get_lang($row['title']),
1354
                            get_lang($row['comment']),
1355
                            get_lang('MB')
1356
                        ),
1357
                        array('maxlength' => '8', 'aria-label' => get_lang($row['title']))
1358
                    );
1359
                    $form->applyFilter($row['variable'], 'html_filter');
1360
                    $default_values[$row['variable']] = round($row['selected_value'] / 1024 / 1024, 1);
1361
                } elseif ($row['variable'] == 'account_valid_duration') {
1362
                    $form->addElement(
1363
                        'text',
1364
                        $row['variable'],
1365
                        array(
1366
                            get_lang($row['title']),
1367
                            get_lang($row['comment']),
1368
                        ),
1369
                        array('maxlength' => '5', 'aria-label' => get_lang($row['title']))
1370
                    );
1371
                    $form->applyFilter($row['variable'], 'html_filter');
1372
                    $default_values[$row['variable']] = $row['selected_value'];
1373
1374
                    // For platform character set selection: Conversion of the textfield to a select box with valid values.
1375
                } elseif ($row['variable'] == 'platform_charset') {
1376
                    continue;
1377
                } else {
1378
                    $hideme['class'] = 'col-md-4';
1379
                    $hideme['aria-label'] = get_lang($row['title']);
1380
                    $form->addElement(
1381
                        'text',
1382
                        $row['variable'],
1383
                        array(
1384
                            get_lang($row['title']),
1385
                            get_lang($row['comment'])
1386
                        ),
1387
                        $hideme
1388
                    );
1389
                    $form->applyFilter($row['variable'], 'html_filter');
1390
                    $default_values[$row['variable']] = $row['selected_value'];
1391
                }
1392
                break;
1393
            case 'textarea':
1394
                if ($row['variable'] == 'header_extra_content') {
1395
                    $file = api_get_home_path().'header_extra_content.txt';
1396
                    $value = '';
1397
                    if (file_exists($file)) {
1398
                        $value = file_get_contents($file);
1399
                    }
1400
                    $form->addElement(
1401
                        'textarea',
1402
                        $row['variable'],
1403
                        array(get_lang($row['title']), get_lang($row['comment'])),
1404
                        array('rows' => '10', 'id' => $row['variable']),
1405
                        $hideme
1406
                    );
1407
                    $default_values[$row['variable']] = $value;
1408
                } elseif ($row['variable'] == 'footer_extra_content') {
1409
                    $file = api_get_home_path().'footer_extra_content.txt';
1410
                    $value = '';
1411
                    if (file_exists($file)) {
1412
                        $value = file_get_contents($file);
1413
                    }
1414
                    $form->addElement(
1415
                        'textarea',
1416
                        $row['variable'],
1417
                        array(get_lang($row['title']), get_lang($row['comment'])),
1418
                        array('rows' => '10', 'id' => $row['variable']),
1419
                        $hideme
1420
                    );
1421
                    $default_values[$row['variable']] = $value;
1422
                } else {
1423
                    $form->addElement(
1424
                        'textarea',
1425
                        $row['variable'],
1426
                        array(get_lang($row['title']),
1427
                        get_lang($row['comment'])),
1428
                        array('rows' => '10', 'id' => $row['variable']),
1429
                        $hideme
1430
                    );
1431
                    $default_values[$row['variable']] = $row['selected_value'];
1432
                }
1433
                break;
1434
            case 'radio':
1435
                $values = api_get_settings_options($row['variable']);
1436
                $group = array();
1437 View Code Duplication
                if (is_array($values)) {
1438
                    foreach ($values as $key => $value) {
1439
                        $element = &$form->createElement(
1440
                            'radio',
1441
                            $row['variable'],
1442
                            '',
1443
                            get_lang($value['display_text']),
1444
                            $value['value']
1445
                        );
1446
                        if ($hide_element) {
1447
                            $element->freeze();
1448
                        }
1449
                        $group[] = $element;
1450
                    }
1451
                }
1452
                $form->addGroup(
1453
                    $group,
1454
                    $row['variable'],
1455
                    array(get_lang($row['title']), get_lang($row['comment'])),
1456
                    null,
1457
                    false
1458
                );
1459
                $default_values[$row['variable']] = $row['selected_value'];
1460
                break;
1461
            case 'checkbox':
1462
                // 1. We collect all the options of this variable.
1463
                $sql = "SELECT * FROM $table_settings_current
1464
                        WHERE variable='".$row['variable']."' AND access_url =  1";
1465
1466
                $result = Database::query($sql);
1467
                $group = array();
1468
                while ($rowkeys = Database::fetch_array($result)) {
1469
                    // Profile tab option should be hidden when the social tool is enabled.
1470
                    if (api_get_setting('allow_social_tool') == 'true') {
1471
                        if ($rowkeys['variable'] === 'show_tabs' && $rowkeys['subkey'] === 'my_profile') {
1472
                            continue;
1473
                        }
1474
                    }
1475
1476
                    // Hiding the gradebook option.
1477
                    if ($rowkeys['variable'] === 'show_tabs' && $rowkeys['subkey'] === 'my_gradebook') {
1478
                        continue;
1479
                    }
1480
1481
                    $element = &$form->createElement(
1482
                        'checkbox',
1483
                        $rowkeys['subkey'],
1484
                        '',
1485
                        get_lang($rowkeys['subkeytext'])
1486
                    );
1487
1488
                    if ($row['access_url_changeable'] == 1) {
1489
                        // 2. We look into the DB if there is a setting for a specific access_url.
1490
                        $access_url = $_configuration['access_url'];
1491
                        if (empty($access_url)) {
1492
                            $access_url = 1;
1493
                        }
1494
                        $sql = "SELECT selected_value FROM $table_settings_current
1495
                                WHERE
1496
                                    variable='".$rowkeys['variable']."' AND
1497
                                    subkey='".$rowkeys['subkey']."' AND
1498
                                    subkeytext='".$rowkeys['subkeytext']."' AND
1499
                                    access_url =  $access_url";
1500
                        $result_access = Database::query($sql);
1501
                        $row_access = Database::fetch_array($result_access);
1502
                        if ($row_access['selected_value'] === 'true' && !$form->isSubmitted()) {
1503
                            $element->setChecked(true);
1504
                        }
1505
                    } else {
1506
                        if ($rowkeys['selected_value'] === 'true' && !$form->isSubmitted()) {
1507
                            $element->setChecked(true);
1508
                        }
1509
                    }
1510
                    if ($hide_element) {
1511
                        $element->freeze();
1512
                    }
1513
                    $group[] = $element;
1514
                }
1515
                $form->addGroup(
1516
                    $group,
1517
                    $row['variable'],
1518
                    array(get_lang($row['title']), get_lang($row['comment'])),
1519
                    null
1520
                );
1521
                break;
1522
            case 'link':
1523
                $form->addElement('static', null, array(get_lang($row['title']), get_lang($row['comment'])),
1524
                    get_lang('CurrentValue').' : '.$row['selected_value'], $hideme);
1525
                break;
1526
            case 'select':
1527
                /*
1528
                * To populate the list of options, the select type dynamically calls a function that must be called select_ + the name of the variable being displayed.
1529
                * The functions being called must be added to the file settings.lib.php.
1530
                */
1531
                $form->addElement(
1532
                    'select',
1533
                    $row['variable'],
1534
                    array(get_lang($row['title']), get_lang($row['comment'])),
1535
                    call_user_func('select_'.$row['variable']),
1536
                    $hideme
1537
                );
1538
                $default_values[$row['variable']] = $row['selected_value'];
1539
                break;
1540
            case 'custom':
1541
                break;
1542
            case 'select_course':
1543
                $courseSelectOptions = [];
1544
1545
                if (!empty($row['selected_value'])) {
1546
                    $course = $em->find('ChamiloCoreBundle:Course', $row['selected_value']);
1547
1548
                    $courseSelectOptions[$course->getId()] = $course->getTitle();
1549
                }
1550
1551
                $form->addElement(
1552
                    'select_ajax',
1553
                    $row['variable'],
1554
                    [get_lang($row['title']), get_lang($row['comment'])],
1555
                    $courseSelectOptions,
1556
                    ['url' => api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=search_course']
1557
                );
1558
                $default_values[$row['variable']] = $row['selected_value'];
1559
                break;
1560
        }
1561
1562
        switch ($row['variable']) {
1563
            case 'pdf_export_watermark_enable':
1564
                $url = PDF::get_watermark(null);
1565
1566
                if ($url != false) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $url of type string|false against false; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
1567
                    $delete_url = '<a href="?delete_watermark">'.get_lang('DelImage').' '.Display::return_icon('delete.png', get_lang('DelImage')).'</a>';
1568
                    $form->addElement('html', '<div style="max-height:100px; max-width:100px; margin-left:162px; margin-bottom:10px; clear:both;"><img src="'.$url.'" style="margin-bottom:10px;" />'.$delete_url.'</div>');
1569
                }
1570
1571
                $form->addElement('file', 'pdf_export_watermark_path', get_lang('AddWaterMark'));
1572
                $allowed_picture_types = array('jpg', 'jpeg', 'png', 'gif');
1573
                $form->addRule('pdf_export_watermark_path', get_lang('OnlyImagesAllowed').' ('.implode(',', $allowed_picture_types).')', 'filetype', $allowed_picture_types);
1574
1575
                break;
1576
            case 'timezone_value':
1577
                $timezone = $row['selected_value'];
1578
                if (empty($timezone)) {
1579
                    $timezone = api_get_timezone();
1580
                }
1581
                $form->addLabel('', sprintf(get_lang('LocalTimeUsingPortalTimezoneXIsY'), $timezone, api_get_local_time()));
1582
                break;
1583
        }
1584
    } // end for
1585
1586
    if (!empty($settings)) {
1587
        $form->setDefaults($default_values);
1588
    }
1589
    $form->addHtml('<div class="bottom_actions">');
1590
    $form->addButtonSave(get_lang('SaveSettings'));
1591
    $form->addHtml('</div>');
1592
    return $form;
1593
}
1594
1595
/**
1596
 * Searches a platform setting in all categories except from the Plugins category
1597
 * @param string $search
1598
 * @return array
1599
 */
1600
function searchSetting($search)
1601
{
1602
    if (empty($search)) {
1603
        return array();
1604
    }
1605
    $table_settings_current = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
1606
    $sql = "SELECT * FROM $table_settings_current
1607
            WHERE category <> 'Plugins' ORDER BY id ASC ";
1608
    $result = Database::store_result(Database::query($sql), 'ASSOC');
1609
    $settings = array();
1610
1611
    $search = api_strtolower($search);
1612
1613
    if (!empty($result)) {
1614
        foreach ($result as $setting) {
1615
            $found = false;
1616
1617
            $title = api_strtolower(get_lang($setting['title']));
1618
            // try the title
1619
            if (strpos($title, $search) === false) {
1620
                $comment = api_strtolower(get_lang($setting['comment']));
1621
                //Try the comment
1622
                if (strpos($comment, $search) === false) {
1623
                    //Try the variable name
1624
                    if (strpos($setting['variable'], $search) === false) {
1625
                        continue;
1626
                    } else {
1627
                        $found = true;
1628
                    }
1629
                } else {
1630
                    $found = true;
1631
                }
1632
1633
            } else {
1634
                $found = true;
1635
            }
1636
            if ($found) {
1637
                $settings[] = $setting;
1638
            }
1639
        }
1640
    }
1641
    return $settings;
1642
}
1643
/**
1644
 * Helper function to generates a form elements group
1645
 * @param object $form The form where the elements group has to be added
1646
 * @param array $values Values to browse through
1647
 * @return array
1648
 */
1649
function formGenerateElementsGroup($form, $values = array(), $elementName)
1650
{
1651
    $group = array();
1652 View Code Duplication
    if (is_array($values)) {
1653
        foreach ($values as $key => $value) {
1654
            $element = &$form->createElement('radio', $elementName, '', get_lang($value['display_text']), $value['value']);
1655
            $group[] = $element;
1656
        }
1657
    }
1658
    return $group;
1659
}
1660
/**
1661
 * Helper function with allowed file types for CSS
1662
 * @return  array Array of file types (no indexes)
1663
 */
1664
function getAllowedFileTypes()
1665
{
1666
    $allowedFiles = array(
1667
        'css',
1668
        'zip',
1669
        'jpeg',
1670
        'jpg',
1671
        'png',
1672
        'gif',
1673
        'ico',
1674
        'psd',
1675
        'xcf',
1676
        'svg',
1677
        'webp',
1678
        'woff',
1679
        'woff2'
1680
    );
1681
    return $allowedFiles;
1682
}
1683
/**
1684
 * Helper function to set settings in the database
1685
 * @param   array   $parameters     List of values
1686
 * @param   int     $accessUrl      The current access URL
1687
 * @return  void
1688
 */
1689
function setConfigurationSettingsInDatabase($parameters, $accessUrl)
1690
{
1691
    api_set_settings_category('Search', 'false', $accessUrl);
1692
    // Save the settings.
1693
    foreach ($parameters as $key => $value) {
1694
        api_set_setting($key, $value, null, null);
1695
    }
1696
}
1697
1698
/**
1699
 * Helper function to show the status of the search settings table
1700
 * @param   array   $data   Data to show
1701
 * @return void
1702
 */
1703
function showSearchSettingsTable($data)
1704
{
1705
    echo Display::tag('h3', get_lang('Settings'));
1706
    $table = new SortableTableFromArray($data);
1707
    $table->set_header(0, get_lang('Setting'), false);
1708
    $table->set_header(1, get_lang('Status'), false);
1709
    echo $table->display();
1710
}
1711
/**
1712
 * Helper function to show status table for each command line tool installed
1713
 * @return void
1714
 */
1715
function showSearchToolsStatusTable()
1716
{
1717
    //@todo windows support
1718
    if (api_is_windows_os() == false) {
1719
        $list_of_programs = array('pdftotext', 'ps2pdf', 'catdoc', 'html2text', 'unrtf', 'catppt', 'xls2csv');
1720
        foreach ($list_of_programs as $program) {
1721
            $output = [];
1722
            $ret_val = null;
1723
            exec("which $program", $output, $ret_val);
1724
1725
            if (!$output) {
1726
                $output[] = '';
1727
            }
1728
1729
            $icon = Display::return_icon('bullet_red.png', get_lang('NotInstalled'));
1730
            if (!empty($output[0])) {
1731
                $icon = Display::return_icon('bullet_green.png', get_lang('Installed'));
1732
            }
1733
            $data2[] = array($program, $output[0], $icon);
1734
        }
1735
        echo Display::tag('h3', get_lang('ProgramsNeededToConvertFiles'));
1736
        $table = new SortableTableFromArray($data2);
1737
        $table->set_header(0, get_lang('Program'), false);
1738
        $table->set_header(1, get_lang('Path'), false);
1739
        $table->set_header(2, get_lang('Status'), false);
1740
        echo $table->display();
1741
    } else {
1742
        echo Display::return_message(
1743
            get_lang('YouAreUsingChamiloInAWindowsPlatformSadlyYouCantConvertDocumentsInOrderToSearchTheContentUsingThisTool'),
1744
            'warning'
1745
        );
1746
    }
1747
}
1748
/**
1749
 * Helper function to generate and show CSS Zip download message
1750
 * @param   string $style Style path
1751
 * @return void
1752
 */
1753
function generateCSSDownloadLink($style)
1754
{
1755
    $arch = api_get_path(SYS_ARCHIVE_PATH).$style.'.zip';
1756
    $themeDir = Template::getThemeDir($style);
1757
    $dir = api_get_path(SYS_CSS_PATH).$themeDir;
1758
    $check = Security::check_abs_path(
1759
        $dir,
1760
        api_get_path(SYS_CSS_PATH).'themes'
1761
    );
1762
    if (is_dir($dir) && $check) {
1763
        $zip = new PclZip($arch);
1764
        // Remove path prefix except the style name and put file on disk
1765
        $zip->create($dir, PCLZIP_OPT_REMOVE_PATH, substr($dir, 0, -strlen($style)));
1766
        $url = api_get_path(WEB_CODE_PATH).'course_info/download.php?archive_path=&archive='.str_replace(api_get_path(SYS_ARCHIVE_PATH), '', $arch);
1767
1768
        //@TODO: use more generic script to download.
1769
        $str = '<a class="btn btn-primary btn-large" href="'.$url.'">'.get_lang('ClickHereToDownloadTheFile').'</a>';
1770
        echo Display::return_message($str, 'normal', false);
1771
    } else {
1772
        echo Display::return_message(get_lang('FileNotFound'), 'warning');
1773
    }
1774
}
1775
1776
/**
1777
 * Helper function to tell if the style is changeable in the current URL
1778
 * @return bool $changeable Whether the style can be changed in this URL or not
1779
 */
1780
function isStyleChangeable()
1781
{
1782
    $changeable = false;
1783
    $urlId = api_get_current_access_url_id();
1784
    if ($urlId) {
1785
        $style_info = api_get_settings('stylesheets', '', 1, 0);
1786
        $url_info = api_get_access_url($urlId);
1787
        if ($style_info[0]['access_url_changeable'] == 1 && $url_info['active'] == 1) {
1788
            $changeable = true;
1789
        }
1790
    } else {
1791
        $changeable = true;
1792
    }
1793
    return $changeable;
1794
}
1795
1796
/**
1797
 * Get all settings of one category prepared for display in admin/settings.php
1798
 * @param string $category
1799
 * @return array
1800
 */
1801
function getCategorySettings($category = '')
1802
{
1803
    $url_id = api_get_current_access_url_id();
1804
    $settings_by_access_list = array();
1805
1806
    if ($url_id == 1) {
1807
        $settings = api_get_settings($category, 'group', $url_id);
1808
    } else {
1809
        $url_info = api_get_access_url($url_id);
1810
        if ($url_info['active'] == 1) {
1811
            $categoryToSearch = $category;
1812
            if ($category == 'search_setting') {
1813
                $categoryToSearch = '';
1814
            }
1815
            // The default settings of Chamilo
1816
            $settings = api_get_settings($categoryToSearch, 'group', 1, 0);
1817
            // The settings that are changeable from a particular site.
1818
            $settings_by_access = api_get_settings($categoryToSearch, 'group', $url_id, 1);
1819
1820
            foreach ($settings_by_access as $row) {
1821
                if (empty($row['variable'])) {
1822
                    $row['variable'] = 0;
1823
                }
1824
                if (empty($row['subkey'])) {
1825
                    $row['subkey'] = 0;
1826
                }
1827
                if (empty($row['category'])) {
1828
                    $row['category'] = 0;
1829
                }
1830
1831
                // One more validation if is changeable.
1832
                if ($row['access_url_changeable'] == 1) {
1833
                    $settings_by_access_list[$row['variable']][$row['subkey']][$row['category']] = $row;
1834
                } else {
1835
                    $settings_by_access_list[$row['variable']][$row['subkey']][$row['category']] = array();
1836
                }
1837
            }
1838
        }
1839
    }
1840
1841
    if (isset($category) && $category == 'search_setting') {
1842
        if (!empty($_REQUEST['search_field'])) {
1843
            $settings = searchSetting($_REQUEST['search_field']);
1844
        }
1845
    }
1846
1847
    return array(
1848
        'settings' => $settings,
1849
        'settings_by_access_list' => $settings_by_access_list
1850
    );
1851
}
1852