Completed
Push — master ( fd29c3...7c77d2 )
by Julito
91:07 queued 30:09
created

settings.lib.php ➔ storeRegions()   D

Complexity

Conditions 10
Paths 12

Size

Total Lines 33
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 18
c 0
b 0
f 0
nc 12
nop 0
dl 0
loc 33
rs 4.8196

How to fix   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
 * Library of the settings.php file
8
 *
9
 * @author Julio Montoya <[email protected]>
10
 * @author Guillaume Viguier <[email protected]>
11
 *
12
 * @since Chamilo 1.8.7
13
 * @package chamilo.admin
14
 */
15
16
define('CSS_UPLOAD_PATH', api_get_path(SYS_APP_PATH).'Resources/public/css/themes/');
17
18
/**
19
 * This function allows easy activating and inactivating of regions
20
 * @author Julio Montoya <[email protected]> Beeznest 2012
21
 */
22
function handleRegions()
23
{
24 View Code Duplication
    if (isset($_POST['submit_plugins'])) {
25
        storeRegions();
26
        // Add event to the system log.
27
        $user_id = api_get_user_id();
28
        $category = $_GET['category'];
29
        Event::addEvent(
30
            LOG_CONFIGURATION_SETTINGS_CHANGE,
31
            LOG_CONFIGURATION_SETTINGS_CATEGORY,
32
            $category,
33
            api_get_utc_datetime(),
34
            $user_id
35
        );
36
        Display :: display_confirmation_message(get_lang('SettingsStored'));
37
    }
38
39
    $plugin_obj = new AppPlugin();
40
    $possible_plugins  = $plugin_obj->read_plugins_from_path();
41
    $installed_plugins = $plugin_obj->get_installed_plugins();
42
43
    echo '<form name="plugins" method="post" action="'.api_get_self().'?category='.Security::remove_XSS($_GET['category']).'">';
44
    echo '<table class="data_table">';
45
    echo '<tr>';
46
    echo '<th width="400px">';
47
    echo get_lang('Plugin');
48
    echo '</th><th>';
49
    echo get_lang('Regions');
50
    echo '</th>';
51
    echo '</th>';
52
    echo '</tr>';
53
54
    /* We display all the possible plugins and the checkboxes */
55
56
    $plugin_region_list = array();
57
    $my_plugin_list = $plugin_obj->get_plugin_regions();
58
    foreach ($my_plugin_list as $plugin_item) {
59
        $plugin_region_list[$plugin_item] = $plugin_item;
60
    }
61
62
    // Removing course tool
63
    unset($plugin_region_list['course_tool_plugin']);
64
65
    foreach ($installed_plugins as $pluginName) {
66
        $plugin_info_file = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/plugin.php';
67
68
        if (file_exists($plugin_info_file)) {
69
            $plugin_info = array();
70
            require $plugin_info_file;
71
            if (isset($_GET['name']) && $_GET['name'] === $pluginName) {
72
                echo '<tr class="row_selected">';
73
            } else {
74
                echo '<tr>';
75
            }
76
            echo '<td>';
77
            echo '<h4>'.$plugin_info['title'].' <small>v'.$plugin_info['version'].'</small></h4>';
78
            echo '<p>'.$plugin_info['comment'].'</p>';
79
            echo '</td><td>';
80
            $selected_plugins = $plugin_obj->get_areas_by_plugin($pluginName);
81
82
            $region_list = [];
83
84
            $isAdminPlugin = isset($plugin_info['is_admin_plugin']) && $plugin_info['is_admin_plugin'];
85
            $isCoursePlugin = isset($plugin_info['is_course_plugin']) && $plugin_info['is_course_plugin'];
86
87
            if (!$isAdminPlugin && !$isCoursePlugin) {
88
                $region_list = $plugin_region_list;
89
            } else {
90
                if ($isAdminPlugin) {
91
                    $region_list['menu_administrator'] = 'menu_administrator';
92
                }
93
                if ($isCoursePlugin) {
94
                    $region_list['course_tool_plugin'] = 'course_tool_plugin';
95
                }
96
            }
97
            echo Display::select(
98
                'plugin_'.$pluginName.'[]',
99
                $region_list,
100
                $selected_plugins,
101
                array('multiple' => 'multiple', 'style' => 'width:500px'),
102
                true,
103
                get_lang('None')
104
            );
105
            echo '</td></tr>';
106
        }
107
    }
108
    echo '</table>';
109
    echo '<br />';
110
    echo '<button class="btn btn-success" type="submit" name="submit_plugins">'.get_lang('EnablePlugins').'</button></form>';
111
}
112
113
function handleExtensions()
114
{
115
    echo Display::page_subheader(get_lang('ConfigureExtensions'));
116
    echo '<a class="btn btn-success" href="configure_extensions.php?display=ppt2lp" role="button">'.get_lang('Ppt2lp').'</a>';
117
118
}
119
/**
120
 * This function allows easy activating and inactivating of plugins
121
 * @todo: a similar function needs to be written to activate or inactivate additional tools.
122
 * @author Patrick Cool <[email protected]>, Ghent University
123
 * @author Julio Montoya <[email protected]> Beeznest 2012
124
 */
125
function handlePlugins()
126
{
127
    $plugin_obj = new AppPlugin();
128
    $token = Security::get_token();
129 View Code Duplication
    if (isset($_POST['submit_plugins'])) {
130
        storePlugins();
131
        // Add event to the system log.
132
        $user_id = api_get_user_id();
133
        $category = $_GET['category'];
134
        Event::addEvent(
135
            LOG_CONFIGURATION_SETTINGS_CHANGE,
136
            LOG_CONFIGURATION_SETTINGS_CATEGORY,
137
            $category,
138
            api_get_utc_datetime(),
139
            $user_id
140
        );
141
        Display :: display_confirmation_message(get_lang('SettingsStored'));
142
    }
143
144
    $all_plugins = $plugin_obj->read_plugins_from_path();
145
    $installed_plugins = $plugin_obj->get_installed_plugins();
146
147
    //Plugins NOT installed
148
    echo Display::page_subheader(get_lang('Plugins'));
149
    echo '<form class="form-horizontal" name="plugins" method="post" action="'.api_get_self().'?category='.Security::remove_XSS($_GET['category']).'&sec_token=' . $token . '">';
150
    echo '<table class="data_table">';
151
    echo '<tr>';
152
    echo '<th width="20px">';
153
    echo get_lang('Action');
154
    echo '</th><th>';
155
    echo get_lang('Description');
156
    echo '</th>';
157
    echo '</tr>';
158
159
    /*$plugin_list = array();
160
    $my_plugin_list = $plugin_obj->get_plugin_regions();
161
    foreach($my_plugin_list as $plugin_item) {
162
        $plugin_list[$plugin_item] = $plugin_item;
163
    }*/
164
165
    foreach ($all_plugins as $pluginName) {
166
        $plugin_info_file = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/plugin.php';
167
168
        if (file_exists($plugin_info_file)) {
169
            $plugin_info = array();
170
            require $plugin_info_file;
171
172
            if (in_array($pluginName, $installed_plugins)) {
173
                echo '<tr class="row_selected">';
174
            } else {
175
                echo '<tr>';
176
            }
177
            echo '<td>';
178
            //Checkbox
179
            if (in_array($pluginName, $installed_plugins)) {
180
                echo '<input type="checkbox" name="plugin_'.$pluginName.'[]" checked="checked">';
181
182
            } else {
183
                echo '<input type="checkbox" name="plugin_'.$pluginName.'[]">';
184
            }
185
            echo '</td><td>';
186
187
            echo '<h4>'.$plugin_info['title'].' <small>v '.$plugin_info['version'].'</small></h4>';
188
            echo '<p>'.$plugin_info['comment'].'</p>';
189
            echo '<p>'.get_lang('Author').': '.$plugin_info['author'].'</p>';
190
191
            echo '<div class="btn-group">';
192
            if (in_array($pluginName, $installed_plugins)) {
193
                echo Display::url('<em class="fa fa-cogs"></em> '.get_lang('Configure'), 'configure_plugin.php?name='.$pluginName, array('class' => 'btn btn-default'));
194
                echo Display::url('<em class="fa fa-th-large"></em> '.get_lang('Regions'), 'settings.php?category=Regions&name='.$pluginName, array('class' => 'btn btn-default'));
195
            }
196
197
            if (file_exists(api_get_path(SYS_PLUGIN_PATH).$pluginName.'/readme.txt')) {
198
                echo Display::url(
199
                    "<em class='fa fa-file-text-o'></em> readme.txt",
200
                    api_get_path(WEB_PLUGIN_PATH) . $pluginName . "/readme.txt",
201
                    [
202
                        'class' => 'btn btn-default ajax',
203
                        'data-title' => $plugin_info['title'],
204
                        'data-size' => 'lg',
205
                        '_target' => '_blank'
206
                    ]
207
                );
208
            }
209
            $readmeFile = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/README.md';
210
            if (file_exists($readmeFile)) {
211
                echo Display::url(
212
                    "<em class='fa fa-file-text-o'></em> README.md",
213
                    api_get_path(WEB_AJAX_PATH).'plugin.ajax.php?a=md_to_html&plugin='.$pluginName,
214
                    [
215
                        'class' => 'btn btn-default ajax',
216
                        'data-title' => $plugin_info['title'],
217
                        'data-size' => 'lg',
218
                        '_target' => '_blank'
219
                    ]
220
                );
221
            }
222
            echo '</div>';
223
            echo '</td></tr>';
224
        }
225
    }
226
    echo '</table>';
227
228
    echo '<div class="form-actions bottom_actions">';
229
    echo '<button class="btn btn-success" type="submit" name="submit_plugins">'.
230
            get_lang('EnablePlugins').'</button>';
231
    echo '</div>';
232
    echo '</form>';
233
}
234
235
/**
236
 * This function allows the platform admin to choose the default stylesheet
237
 * @author Patrick Cool <[email protected]>, Ghent University
238
 * @author Julio Montoya <[email protected]>, Chamilo
239
 */
240
function handleStylesheets()
241
{
242
    global $_configuration;
243
244
    // Current style.
245
    $currentstyle = api_get_setting('stylesheets');
246
247
    $is_style_changeable = isStyleChangeable();
248
249
    $form = new FormValidator(
250
        'stylesheet_upload',
251
        'post',
252
        'settings.php?category=Stylesheets#tabs-3'
253
    );
254
    $form->addElement('text', 'name_stylesheet', get_lang('NameStylesheet'),
255
        array('size' => '40', 'maxlength' => '40'));
256
    $form->addRule('name_stylesheet', get_lang('ThisFieldIsRequired'), 'required');
257
    $form->addElement('file', 'new_stylesheet', get_lang('UploadNewStylesheet'));
258
    $allowed_file_types = getAllowedFileTypes();
259
260
    $form->addRule('new_stylesheet', get_lang('InvalidExtension') . ' (' . implode(',', $allowed_file_types) . ')',
261
        'filetype', $allowed_file_types);
262
    $form->addRule('new_stylesheet', get_lang('ThisFieldIsRequired'), 'required');
263
    $form->addButtonUpload(get_lang('Upload'), 'stylesheet_upload');
264
265
    $show_upload_form = false;
266
267
    if (!is_writable(CSS_UPLOAD_PATH)) {
268
        Display::display_error_message(CSS_UPLOAD_PATH.get_lang('IsNotWritable'));
269
    } else {
270
        // Uploading a new stylesheet.
271
        if ($_configuration['access_url'] == 1) {
272
            $show_upload_form = true;
273
        } else {
274
            if ($is_style_changeable) {
275
                $show_upload_form = true;
276
            }
277
        }
278
    }
279
280
    // Stylesheet upload.
281
282
    if (isset($_POST['stylesheet_upload'])) {
283
        if ($form->validate()) {
284
            $values = $form->exportValues();
285
            $picture_element = $form->getElement('new_stylesheet');
286
            $picture = $picture_element->getValue();
287
            $result = uploadStylesheet($values, $picture);
288
289
            // Add event to the system log.
290
            $user_id = api_get_user_id();
291
            $category = $_GET['category'];
292
            Event::addEvent(
293
                LOG_CONFIGURATION_SETTINGS_CHANGE,
294
                LOG_CONFIGURATION_SETTINGS_CATEGORY,
295
                $category,
296
                api_get_utc_datetime(),
297
                $user_id
298
            );
299
300
            if ($result) {
301
                Display::display_confirmation_message(get_lang('StylesheetAdded'));
302
            }
303
        }
304
    }
305
306
    $form_change = new FormValidator(
307
        'stylesheet_upload',
308
        'post',
309
        api_get_self().'?category=Stylesheets',
310
        null,
311
        array('id' => 'stylesheets_id')
312
    );
313
314
    $list_of_names  = array();
315
    $selected = '';
316
    $dirpath = '';
317
    $safe_style_dir = '';
318
319
    if ($handle = @opendir(CSS_UPLOAD_PATH)) {
320
        $counter = 1;
321
        while (false !== ($style_dir = readdir($handle))) {
322
            if (substr($style_dir, 0, 1) == '.') {
323
                // Skip directories starting with a '.'
324
                continue;
325
            }
326
            $dirpath = CSS_UPLOAD_PATH.$style_dir;
327
328
            if (is_dir($dirpath)) {
329
                if ($style_dir != '.' && $style_dir != '..') {
330
                    if (isset($_POST['style']) &&
331
                        (isset($_POST['preview']) || isset($_POST['download'])) &&
332
                        $_POST['style'] == $style_dir
333
                    ) {
334
                        $safe_style_dir = $style_dir;
335
                    } else {
336
                        if ($currentstyle == $style_dir || ($style_dir == 'chamilo' && !$currentstyle)) {
337
                            if (isset($_POST['style'])) {
338
                                $selected = Database::escape_string($_POST['style']);
339
                            } else {
340
                                $selected = $style_dir;
341
                            }
342
                        }
343
                    }
344
                    $show_name = ucwords(str_replace('_', ' ', $style_dir));
345
346
                    if ($is_style_changeable) {
347
                        $list_of_names[$style_dir]  = $show_name;
348
                    }
349
                    $counter++;
350
                }
351
            }
352
        }
353
        closedir($handle);
354
    }
355
356
    // Sort styles in alphabetical order.
357
    asort($list_of_names);
358
    $select_list = array();
359
    foreach ($list_of_names as $style_dir => $item) {
360
        $select_list[$style_dir] = $item;
361
    }
362
363
    $styles = &$form_change->addElement('select', 'style', get_lang('NameStylesheet'), $select_list);
364
    $styles->setSelected($selected);
365
366
    if ($form_change->validate()) {
367
        // Submit stylesheets.
368
        if (isset($_POST['save'])) {
369
            storeStylesheets();
370
            Display::display_normal_message(get_lang('Saved'));
371
        }
372
        if (isset($_POST['download'])) {
373
            generateCSSDownloadLink($safe_style_dir);
374
        }
375
    }
376
    
377
    $logoForm = new FormValidator(
378
        'logo_upload',
379
        'post',
380
        'settings.php?category=Stylesheets#tabs-2'
381
    );
382
    
383
    $logoForm->addHtml(
384
        Display::return_message(sprintf(get_lang('TheLogoMustBeSizeXAndFormatY'), '250 x 70', 'PNG'), 'info')
385
    );
386
    
387
    $dir = api_get_path(SYS_PUBLIC_PATH).'css/themes/' . $selected . '/images/';
388
    $url = api_get_path(WEB_CSS_PATH).'themes/' . $selected . '/images/';
389
    $logoFileName = 'header-logo.png';
390
    $newLogoFileName = 'header-logo-custom' . api_get_current_access_url_id() . '.png';
391
    $webPlatformLogoPath = ChamiloApi::getWebPlatformLogoPath();
392
    
393
    if ($webPlatformLogoPath !== null) {
394
        $logoForm->addLabel(
395
            get_lang('CurrentLogo'),
396
            '<img id="header-logo-custom" src="' . $webPlatformLogoPath . '?' . time() . '">'
397
        );
398
    }
399
    
400
    $logoForm->addFile('new_logo', get_lang('UpdateLogo'));
401
    $allowedFileTypes = ['png'];
402
    
403
    if (isset($_POST['logo_reset'])) {
404
        if (is_file($dir.$newLogoFileName)) {
405
            unlink($dir.$newLogoFileName);
406
            echo Display::return_message(get_lang('ResetToTheOriginalLogo'));
407
            echo '<script>'
408
                . '$("#header-logo").attr("src","'.$url.$logoFileName.'");'
409
            . '</script>';
410
        }
411
    } elseif (isset($_POST['logo_upload'])) {
412
        
413
        $logoForm->addRule('new_logo', get_lang('InvalidExtension').' ('.implode(',', $allowedFileTypes).')', 'filetype', $allowedFileTypes);
414
        $logoForm->addRule('new_logo', get_lang('ThisFieldIsRequired'), 'required');
415
        
416
        if ($logoForm->validate()) {
417
            
418
            $imageInfo = getimagesize($_FILES['new_logo']['tmp_name']);
419
            $width = $imageInfo[0];
420
            $height = $imageInfo[1];
421
            if ($width <= 250 && $height <= 70 ) {
422
                if (is_file($dir.$newLogoFileName)) {
423
                    unlink($dir.$newLogoFileName);
424
                }
425
                
426
                $status = move_uploaded_file($_FILES['new_logo']['tmp_name'], $dir.$newLogoFileName);
427
428
                if ($status) {
429
                    echo Display::return_message(get_lang('NewLogoUpdated'));
430
                    echo '<script>'
431
                            . '$("#header-logo").attr("src","'.$url.$newLogoFileName.'");'
432
                        . '</script>';
433
                } else {
434
                    echo Display::return_message('Error - '.get_lang('UplNoFileUploaded'), 'error');
435
                }
436
            } else {
437
                Display::return_message('Error - '.get_lang('InvalidImageDimensions'), 'error');
438
            }
439
        }
440
    }
441
442
    if ($is_style_changeable) {
443
        $group = [
444
            $form_change->addButtonSave(get_lang('SaveSettings'), 'save', true),
445
            $form_change->addButtonPreview(get_lang('Preview'), 'preview', true),
446
            $form_change->addButtonDownload(get_lang('Download'), 'download', true)
447
        ];
448
449
        $form_change->addGroup($group);
450
        
451
        $logoGroup = [
452
            $logoForm->addButtonUpload(get_lang('Upload'), 'logo_upload', true),
453
            $logoForm->addButtonCancel(get_lang('Reset'), 'logo_reset', true)
454
        ];
455
        
456
        $logoForm->addGroup($logoGroup);
457
458
        if ($show_upload_form) {
459
            echo '<script>
460
            $(function() {
461
                $( "#tabs" ).tabs();
462
            });
463
            </script>';
464
            echo Display::tabs(
465
                array(get_lang('Update'),get_lang('UpdateLogo'), get_lang('UploadNewStylesheet')),
466
                array($form_change->return_form(), $logoForm->returnForm(), $form->returnForm())
0 ignored issues
show
Deprecated Code introduced by
The method FormValidator::return_form() has been deprecated with message: use returnForm()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
467
            );
468
        } else {
469
            $form_change->display();
470
        }
471
        
472
        //Little hack to update the logo image in update form when submiting
473
        if (isset($_POST['logo_reset'])) {
474
            echo '<script>'
475
                    . '$("#header-logo-custom").attr("src","'.$url.$logoFileName.'");'
476
                . '</script>';
477
        } elseif (isset($_POST['logo_upload']) && is_file($dir.$newLogoFileName)) {
478
            echo '<script>'
479
                    . '$("#header-logo-custom").attr("src","'.$url.$newLogoFileName.'");'
480
                . '</script>';
481
        }
482
    } else {
483
        $form_change->freeze();
484
    }
485
}
486
487
/**
488
 * Creates the folder (if needed) and uploads the stylesheet in it
489
 * @param array $values the values of the form
490
 * @param array $picture the values of the uploaded file
491
 * @return bool
492
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
493
 * @version May 2008
494
 * @since v1.8.5
495
 */
496
function uploadStylesheet($values, $picture)
497
{
498
    $result = false;
499
    // Valid name for the stylesheet folder.
500
    $style_name = api_preg_replace('/[^A-Za-z0-9]/', '', $values['name_stylesheet']);
501
    $cssToUpload = CSS_UPLOAD_PATH;
502
503
    // Create the folder if needed.
504
505
    if (!is_dir($cssToUpload.$style_name.'/')) {
506
        mkdir($cssToUpload.$style_name.'/', api_get_permissions_for_new_directories());
507
    }
508
509
    $info = pathinfo($picture['name']);
510
511
    if ($info['extension'] == 'zip') {
512
        // Try to open the file and extract it in the theme.
513
        $zip = new ZipArchive();
514
        if ($zip->open($picture['tmp_name'])) {
515
            // Make sure all files inside the zip are images or css.
516
            $num_files = $zip->numFiles;
517
            $valid = true;
518
            $single_directory = true;
519
            $invalid_files = array();
520
521
            $allowedFiles = getAllowedFileTypes();
522
523
            for ($i = 0; $i < $num_files; $i++) {
524
                $file = $zip->statIndex($i);
525
                if (substr($file['name'], -1) != '/') {
526
                    $path_parts = pathinfo($file['name']);
527
                    if (!in_array($path_parts['extension'], $allowedFiles)) {
528
                        $valid = false;
529
                        $invalid_files[] = $file['name'];
530
                    }
531
                }
532
533
                if (strpos($file['name'], '/') === false) {
534
                    $single_directory = false;
535
                }
536
            }
537
            if (!$valid) {
538
                $error_string = '<ul>';
539
                foreach ($invalid_files as $invalid_file) {
540
                    $error_string .= '<li>'.$invalid_file.'</li>';
541
                }
542
                $error_string .= '</ul>';
543
                Display::display_error_message(
544
                    get_lang('ErrorStylesheetFilesExtensionsInsideZip').$error_string,
545
                    false
546
                );
547
            } else {
548
                // If the zip does not contain a single directory, extract it.
549
                if (!$single_directory) {
550
                    // Extract zip file.
551
                    $zip->extractTo($cssToUpload.$style_name.'/');
552
                    $result = true;
553
                } else {
554
                    $extraction_path = $cssToUpload.$style_name.'/';
555
                    for ($i = 0; $i < $num_files; $i++) {
556
                        $entry = $zip->getNameIndex($i);
557
                        if (substr($entry, -1) == '/') {
558
                            continue;
559
                        }
560
561
                        $pos_slash = strpos($entry, '/');
562
                        $entry_without_first_dir = substr($entry, $pos_slash + 1);
563
                        // If there is still a slash, we need to make sure the directories are created.
564
                        if (strpos($entry_without_first_dir, '/') !== false) {
565
                            if (!is_dir($extraction_path.dirname($entry_without_first_dir))) {
566
                                // Create it.
567
                                @mkdir($extraction_path.dirname($entry_without_first_dir), $mode = 0777, true);
568
                            }
569
                        }
570
571
                        $fp = $zip->getStream($entry);
572
                        $ofp = fopen($extraction_path.dirname($entry_without_first_dir).'/'.basename($entry), 'w');
573
574
                        while (!feof($fp)) {
575
                            fwrite($ofp, fread($fp, 8192));
576
                        }
577
578
                        fclose($fp);
579
                        fclose($ofp);
580
                    }
581
                    $result = true;
582
                }
583
            }
584
            $zip->close();
585
        } else {
586
            Display::display_error_message(get_lang('ErrorReadingZip').$info['extension'], false);
587
        }
588
    } else {
589
        // Simply move the file.
590
        move_uploaded_file($picture['tmp_name'], $cssToUpload.$style_name.'/'.$picture['name']);
591
        $result = true;
592
    }
593
594
    if ($result) {
595
        $fs = new Filesystem();
596
        $fs->mirror($cssToUpload, api_get_path(SYS_PATH).'web/css/themes/');
597
    }
598
599
    return $result;
600
}
601
602
/**
603
 * Store plugin regions.
604
 */
605
function storeRegions()
606
{
607
    $plugin_obj = new AppPlugin();
608
609
    // Get a list of all current 'Plugins' settings
610
    $installed_plugins = $plugin_obj->get_installed_plugins();
611
612
    $shortlist_installed = array();
613
    if (!empty($installed_plugins)) {
614
        foreach ($installed_plugins as $plugin) {
615
            if (isset($plugin['subkey'])) {
616
                $shortlist_installed[] = $plugin['subkey'];
617
            }
618
        }
619
    }
620
    $shortlist_installed = array_flip(array_flip($shortlist_installed));
621
622
    $plugin_list = $plugin_obj->read_plugins_from_path();
623
624
    foreach ($plugin_list as $plugin) {
625
        if (isset($_POST['plugin_'.$plugin])) {
626
            $areas_to_installed = $_POST['plugin_'.$plugin];
627
            if (!empty($areas_to_installed)) {
628
                $plugin_obj->remove_all_regions($plugin);
629
                foreach ($areas_to_installed as $region) {
630
                    if (!empty($region) && $region != '-1' ) {
631
                        $plugin_obj->add_to_region($plugin, $region);
632
                    }
633
                }
634
            }
635
        }
636
    }
637
}
638
639
/**
640
 * This function allows easy activating and inactivating of plugins
641
 * @author Patrick Cool <[email protected]>, Ghent University
642
 */
643
function storePlugins()
644
{
645
    $appPlugin = new AppPlugin();
646
647
    // Get a list of all current 'Plugins' settings
648
    $plugin_list = $appPlugin->read_plugins_from_path();
649
650
    $installed_plugins = array();
651
652
    foreach ($plugin_list as $plugin) {
653
        if (isset($_POST['plugin_'.$plugin])) {
654
            $appPlugin->install($plugin);
655
            $installed_plugins[] = $plugin;
656
        }
657
    }
658
659
    if (!empty($installed_plugins)) {
660
        $remove_plugins = array_diff($plugin_list, $installed_plugins);
661
    } else {
662
        $remove_plugins = $plugin_list;
663
    }
664
665
    foreach ($remove_plugins as $plugin) {
666
        $appPlugin->uninstall($plugin);
667
    }
668
}
669
670
/**
671
 * This function allows the platform admin to choose which should be the default stylesheet
672
 * @author Patrick Cool <[email protected]>, Ghent University
673
 */
674
function storeStylesheets()
675
{
676
    // Insert the stylesheet.
677
    if (isStyle($_POST['style'])) {
678
        api_set_setting(
679
            'stylesheets',
680
            $_POST['style'],
681
            null,
682
            'stylesheets',
683
            api_get_current_access_url_id()
684
        );
685
    }
686
    return true;
687
}
688
689
/**
690
 * This function checks if the given style is a recognize style that exists in the css directory as
691
 * a standalone directory.
692
 * @param string    Style
693
 * @return bool     True if this style is recognized, false otherwise
694
 */
695
function isStyle($style)
696
{
697
    $dir = CSS_UPLOAD_PATH;
698
    $dirs = scandir($dir);
699
    $style = str_replace(array('/', '\\'), array('', ''), $style); // Avoid slashes or backslashes.
700
    if (in_array($style, $dirs) && is_dir($dir.$style)) {
701
        return true;
702
    }
703
    return false;
704
}
705
706
/**
707
 * Search options
708
 * TODO: support for multiple site. aka $_configuration['access_url'] == 1
709
 * @author Marco Villegas <[email protected]>
710
 */
711
function handleSearch()
712
{
713
    global $SettingsStored, $_configuration;
714
715
    require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
716
    $search_enabled = api_get_setting('search.search_enabled');
717
718
    $form = new FormValidator('search-options', 'post', api_get_self().'?category=Search');
719
    $values = api_get_settings_options('search_enabled');
720
    $form->addElement('header', null, get_lang('SearchEnabledTitle'));
721
722
    $group = formGenerateElementsGroup($form, $values, 'search_enabled');
723
    //SearchEnabledComment
724
    $form->addGroup($group, 'search_enabled', array(get_lang('SearchEnabledTitle'), get_lang('SearchEnabledComment')), null, false);
725
726
    $search_enabled = api_get_setting('search_enabled');
727
728 View Code Duplication
    if ($form->validate()) {
729
        $formValues = $form->exportValues();
730
        setConfigurationSettingsInDatabase($formValues, $_configuration['access_url']);
731
        $search_enabled = $formValues['search_enabled'];
732
        Display::display_confirmation_message($SettingsStored);
733
    }
734
    $specific_fields = get_specific_field_list();
735
736
    if ($search_enabled == 'true') {
737
        $values = api_get_settings_options('search_show_unlinked_results');
738
        $group = formGenerateElementsGroup($form, $values, 'search_show_unlinked_results');
739
        $form->addGroup($group, 'search_show_unlinked_results', array(get_lang('SearchShowUnlinkedResultsTitle'),get_lang('SearchShowUnlinkedResultsComment')), null, false);
740
        $default_values['search_show_unlinked_results'] = api_get_setting('search_show_unlinked_results');
741
742
        $sf_values = array();
743
        foreach ($specific_fields as $sf) {
744
            $sf_values[$sf['code']] = $sf['name'];
745
        }
746
        $url =  Display::div(Display::url(get_lang('AddSpecificSearchField'), 'specific_fields.php'), array('class'=>'sectioncomment'));
747
        if (empty($sf_values)) {
748
            $form->addElement('label', [get_lang('SearchPrefilterPrefix'), $url]);
749
        } else {
750
            $form->addElement('select', 'search_prefilter_prefix', array(get_lang('SearchPrefilterPrefix'), $url), $sf_values, '');
751
            $default_values['search_prefilter_prefix'] = api_get_setting('search_prefilter_prefix');
752
        }
753
    }
754
755
    $default_values['search_enabled'] = $search_enabled;
756
757
    $form->addButtonSave(get_lang('Save'));
758
    $form->setDefaults($default_values);
759
760
    echo '<div id="search-options-form">';
761
    $form->display();
762
    echo '</div>';
763
764
    if ($search_enabled == 'true') {
765
        $xapianPath = api_get_path(SYS_UPLOAD_PATH).'plugins/xapian/searchdb';
766
767
        /*
768
        @todo Test the Xapian connection
769
        if (extension_loaded('xapian')) {
770
            require_once 'xapian.php';
771
            try {
772
                $db = new XapianDatabase($xapianPath.'/');
773
            } catch (Exception $e) {
774
                var_dump($e->getMessage());
775
            }
776
777
            require_once api_get_path(LIBRARY_PATH) . 'search/ChamiloIndexer.class.php';
778
            require_once api_get_path(LIBRARY_PATH) . 'search/IndexableChunk.class.php';
779
            require_once api_get_path(LIBRARY_PATH) . 'specific_fields_manager.lib.php';
780
781
            $indexable = new IndexableChunk();
782
            $indexable->addValue("content", 'Test');
783
784
            $di = new ChamiloIndexer();
785
            $di->connectDb(NULL, NULL, 'english');
786
            $di->addChunk($indexable);
787
            $did = $di->index();
788
        }
789
        */
790
791
        $xapianLoaded = Display::return_icon('bullet_green.png', get_lang('Ok'));
792
        $dir_exists = Display::return_icon('bullet_green.png', get_lang('Ok'));
793
        $dir_is_writable = Display::return_icon('bullet_green.png', get_lang('Ok'));
794
        $specific_fields_exists = Display::return_icon('bullet_green.png', get_lang('Ok'));
795
796
        //Testing specific fields
797
        if (empty($specific_fields)) {
798
            $specific_fields_exists = Display::return_icon('bullet_red.png', get_lang('AddSpecificSearchField'));
799
        }
800
        //Testing xapian extension
801
        if (!extension_loaded('xapian')) {
802
            $xapianLoaded = Display::return_icon('bullet_red.png', get_lang('Error'));
803
        }
804
        //Testing xapian searchdb path
805
        if (!is_dir($xapianPath)) {
806
            $dir_exists = Display::return_icon('bullet_red.png', get_lang('Error'));
807
        }
808
        //Testing xapian searchdb path is writable
809
        if (!is_writable($xapianPath)) {
810
            $dir_is_writable = Display::return_icon('bullet_red.png', get_lang('Error'));
811
        }
812
813
        $data = array();
814
        $data[] = array(get_lang('XapianModuleInstalled'), $xapianLoaded);
815
        $data[] = array(get_lang('DirectoryExists').' - '.$xapianPath, $dir_exists);
816
        $data[] = array(get_lang('IsWritable').' - '.$xapianPath, $dir_is_writable);
817
        $data[] = array(get_lang('SpecificSearchFieldsAvailable') ,$specific_fields_exists);
818
819
        showSearchSettingsTable($data);
820
        showSearchToolsStatusTable();
821
    }
822
}
823
824
/**
825
 * Wrapper for the templates
826
 *
827
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
828
 * @author Julio Montoya.
829
 * @version August 2008
830
 * @since v1.8.6
831
 */
832
function handleTemplates()
833
{
834
    /* Drive-by fix to avoid undefined var warnings, without repeating
835
     * isset() combos all over the place. */
836
    $action = isset($_GET['action']) ? $_GET['action'] : "invalid";
837
838
    if ($action != 'add') {
839
        echo '<div class="actions" style="margin-left: 1px;">';
840
        echo '<a href="settings.php?category=Templates&action=add">'.
841
                Display::return_icon('new_template.png', get_lang('AddTemplate'),'',ICON_SIZE_MEDIUM).'</a>';
842
        echo '</div>';
843
    }
844
845
    if ($action == 'add' || ($action == 'edit' && is_numeric($_GET['id']))) {
846
        addEditTemplate();
847
848
        // Add event to the system log.
849
        $user_id = api_get_user_id();
850
        $category = $_GET['category'];
851
        Event::addEvent(
852
            LOG_CONFIGURATION_SETTINGS_CHANGE,
853
            LOG_CONFIGURATION_SETTINGS_CATEGORY,
854
            $category,
855
            api_get_utc_datetime(),
856
            $user_id
857
        );
858
    } else {
859
        if ($action == 'delete' && is_numeric($_GET['id'])) {
860
            deleteTemplate($_GET['id']);
861
862
            // Add event to the system log
863
            $user_id = api_get_user_id();
864
            $category = $_GET['category'];
865
            Event::addEvent(
866
                LOG_CONFIGURATION_SETTINGS_CHANGE,
867
                LOG_CONFIGURATION_SETTINGS_CATEGORY,
868
                $category,
869
                api_get_utc_datetime(),
870
                $user_id
871
            );
872
        }
873
        displayTemplates();
874
    }
875
}
876
877
/**
878
 * Display a sortable table with all the templates that the platform administrator has defined.
879
 *
880
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
881
 * @version August 2008
882
 * @since v1.8.6
883
 */
884
function displayTemplates()
885
{
886
    $table = new SortableTable('templates', 'getNumberOfTemplates', 'getTemplateData', 1);
887
    $table->set_additional_parameters(array('category' => Security::remove_XSS($_GET['category'])));
888
    $table->set_header(0, get_lang('Image'), true, array('style' => 'width: 101px;'));
889
    $table->set_header(1, get_lang('Title'));
890
    $table->set_header(2, get_lang('Actions'), false, array('style' => 'width:50px;'));
891
    $table->set_column_filter(2, 'actionsFilter');
892
    $table->set_column_filter(0, 'searchImageFilter');
893
    $table->display();
894
}
895
896
/**
897
 * Gets the number of templates that are defined by the platform admin.
898
 *
899
 * @return integer
900
 *
901
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
902
 * @version August 2008
903
 * @since v1.8.6
904
 */
905 View Code Duplication
function getNumberOfTemplates()
906
{
907
    // Database table definition.
908
    $table_system_template = Database :: get_main_table('system_template');
909
910
    // The sql statement.
911
    $sql = "SELECT COUNT(id) AS total FROM $table_system_template";
912
    $result = Database::query($sql);
913
    $row = Database::fetch_array($result);
914
915
    // Returning the number of templates.
916
    return $row['total'];
917
}
918
919
/**
920
 * Gets all the template data for the sortable table.
921
 *
922
 * @param integer $from the start of the limit statement
923
 * @param integer $number_of_items the number of elements that have to be retrieved from the database
924
 * @param integer $column the column that is
925
 * @param string $direction the sorting direction (ASC or DESC�
926
 * @return array
927
 *
928
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
929
 * @version August 2008
930
 * @since v1.8.6
931
 */
932
function getTemplateData($from, $number_of_items, $column, $direction)
933
{
934
    // Database table definition.
935
    $table_system_template = Database :: get_main_table('system_template');
936
937
    // The sql statement.
938
    $sql = "SELECT image as col0, title as col1, id as col2 FROM $table_system_template";
939
    $sql .= " ORDER BY col$column $direction ";
940
    $sql .= " LIMIT $from,$number_of_items";
941
    $result = Database::query($sql);
942
    $return = array();
943
    while ($row = Database::fetch_array($result)) {
944
        $row['1'] = get_lang($row['1']);
945
        $return[] = $row;
946
    }
947
    // Returning all the information for the sortable table.
948
    return $return;
949
}
950
951
/**
952
 * display the edit and delete icons in the sortable table
953
 *
954
 * @param integer $id the id of the template
955
 * @return string code for the link to edit and delete the template
956
 *
957
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
958
 * @version August 2008
959
 * @since v1.8.6
960
 */
961
function actionsFilter($id) {
962
    $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>';
963
    $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>';
964
    return $return;
965
}
966
967
/**
968
 * Display the image of the template in the sortable table
969
 *
970
 * @param string $image the image
971
 * @return string code for the image
972
 *
973
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
974
 * @version August 2008
975
 * @since v1.8.6
976
 */
977
function searchImageFilter($image)
978
{
979
    if (!empty($image)) {
980
        return '<img src="'.api_get_path(WEB_APP_PATH).'home/default_platform_document/template_thumb/'.$image.'" alt="'.get_lang('TemplatePreview').'"/>';
981
    } else {
982
        return '<img src="'.api_get_path(WEB_APP_PATH).'home/default_platform_document/template_thumb/noimage.gif" alt="'.get_lang('NoTemplatePreview').'"/>';
983
    }
984
}
985
986
/**
987
 * Add (or edit) a template. This function displays the form and also takes
988
 * care of uploading the image and storing the information in the database
989
 *
990
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
991
 * @version August 2008
992
 * @since v1.8.6
993
 */
994
function addEditTemplate()
995
{
996
    // Initialize the object.
997
    $id = isset($_GET['id']) ? '&id='.Security::remove_XSS($_GET['id']) : '';
998
    $form = new FormValidator('template', 'post', 'settings.php?category=Templates&action='.Security::remove_XSS($_GET['action']).$id);
999
1000
    // Setting the form elements: the header.
1001
    if ($_GET['action'] == 'add') {
1002
        $title = get_lang('AddTemplate');
1003
    } else {
1004
        $title = get_lang('EditTemplate');
1005
    }
1006
    $form->addElement('header', '', $title);
1007
1008
    // Setting the form elements: the title of the template.
1009
    $form->addText('title', get_lang('Title'), false);
1010
1011
    // Setting the form elements: the content of the template (wysiwyg editor).
1012
    $form->addHtmlEditor(
1013
        'template_text',
1014
        get_lang('Text'),
1015
        false,
1016
        false,
1017
        array(
1018
            'ToolbarSet' => 'AdminTemplates',
1019
            'Width' => '100%',
1020
            'Height' => '400',
1021
        )
1022
    );
1023
1024
    // Setting the form elements: the form to upload an image to be used with the template.
1025
    $form->addElement('file','template_image',get_lang('Image'),'');
1026
1027
    // Setting the form elements: a little bit information about the template image.
1028
    $form->addElement('static', 'file_comment', '', get_lang('TemplateImageComment100x70'));
1029
1030
    // Getting all the information of the template when editing a template.
1031
    if ($_GET['action'] == 'edit') {
1032
        // Database table definition.
1033
        $table_system_template = Database :: get_main_table('system_template');
1034
        $sql = "SELECT * FROM $table_system_template WHERE id = ".intval($_GET['id'])."";
1035
        $result = Database::query($sql);
1036
        $row = Database::fetch_array($result);
1037
1038
        $defaults['template_id']    = intval($_GET['id']);
1039
        $defaults['template_text']  = $row['content'];
1040
        // Forcing get_lang().
1041
        $defaults['title']          = get_lang($row['title']);
1042
1043
        // Adding an extra field: a hidden field with the id of the template we are editing.
1044
        $form->addElement('hidden', 'template_id');
1045
1046
        // Adding an extra field: a preview of the image that is currently used.
1047
        if (!empty($row['image'])) {
1048
            $form->addElement('static', 'template_image_preview', '',
1049
                '<img src="' . api_get_path(WEB_APP_PATH) . 'home/default_platform_document/template_thumb/' . $row['image'] . '" alt="' . get_lang('TemplatePreview') . '"/>');
1050
        } else {
1051
            $form->addElement('static', 'template_image_preview', '',
1052
                '<img src="' . api_get_path(WEB_APP_PATH) . 'home/default_platform_document/template_thumb/noimage.gif" alt="' . get_lang('NoTemplatePreview') . '"/>');
1053
        }
1054
1055
        // Setting the information of the template that we are editing.
1056
        $form->setDefaults($defaults);
1057
    }
1058
    // Setting the form elements: the submit button.
1059
    $form->addButtonSave(get_lang('Ok'), 'submit');
1060
1061
    // Setting the rules: the required fields.
1062
    $form->addRule('template_image', get_lang('ThisFieldIsRequired'), 'required');
1063
    $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
1064
    $form->addRule('template_text', get_lang('ThisFieldIsRequired'), 'required');
1065
1066
    // if the form validates (complies to all rules) we save the information, else we display the form again (with error message if needed)
1067
    if ($form->validate()) {
1068
1069
        $check = Security::check_token('post');
1070
        if ($check) {
1071
            // Exporting the values.
1072
            $values = $form->exportValues();
1073
            // Upload the file.
1074
            if (!empty($_FILES['template_image']['name'])) {
1075
                $upload_ok = process_uploaded_file($_FILES['template_image']);
1076
1077
                if ($upload_ok) {
1078
                    // Try to add an extension to the file if it hasn't one.
1079
                    $new_file_name = add_ext_on_mime(stripslashes($_FILES['template_image']['name']), $_FILES['template_image']['type']);
1080
1081
                    // The upload directory.
1082
                    $upload_dir = api_get_path(SYS_APP_PATH).'home/default_platform_document/template_thumb/';
1083
1084
                    // Create the directory if it does not exist.
1085
                    if (!is_dir($upload_dir)) {
1086
                        mkdir($upload_dir, api_get_permissions_for_new_directories());
1087
                    }
1088
1089
                    // Resize the preview image to max default and upload.
1090
                    $temp = new Image($_FILES['template_image']['tmp_name']);
1091
                    $picture_info = $temp->get_image_info();
1092
1093
                    $max_width_for_picture = 100;
1094
1095
                    if ($picture_info['width'] > $max_width_for_picture) {
1096
                        $temp->resize($max_width_for_picture);
1097
                    }
1098
                    $temp->send_image($upload_dir.$new_file_name);
1099
                }
1100
            }
1101
1102
            // Store the information in the database (as insert or as update).
1103
            $table_system_template = Database :: get_main_table('system_template');
1104
            if ($_GET['action'] == 'add') {
1105
                $content_template =  Security::remove_XSS($values['template_text'], COURSEMANAGERLOWSECURITY);
1106
                $params = [
1107
                    'title' =>  $values['title'],
1108
                    'content' => $content_template,
1109
                    'image' => $new_file_name
1110
                ];
1111
                Database::insert($table_system_template, $params);
1112
1113
                // Display a feedback message.
1114
                Display::display_confirmation_message(get_lang('TemplateAdded'));
1115
                echo '<a href="settings.php?category=Templates&action=add">'.Display::return_icon('new_template.png', get_lang('AddTemplate'),'',ICON_SIZE_MEDIUM).'</a>';
1116
            } else {
1117
                $content_template = '<head>{CSS}<style type="text/css">.text{font-weight: normal;}</style></head><body>'.Database::escape_string($values['template_text']).'</body>';
1118
                $sql = "UPDATE $table_system_template set title = '".Database::escape_string($values['title'])."', content = '".$content_template."'";
1119
                if (!empty($new_file_name)) {
1120
                    $sql .= ", image = '".Database::escape_string($new_file_name)."'";
1121
                }
1122
                $sql .= " WHERE id = ".intval($_GET['id'])."";
1123
                Database::query($sql);
1124
1125
                // Display a feedback message.
1126
                Display::display_confirmation_message(get_lang('TemplateEdited'));
1127
            }
1128
        }
1129
        Security::clear_token();
1130
        displayTemplates();
1131
    } else {
1132
        $token = Security::get_token();
1133
        $form->addElement('hidden','sec_token');
1134
        $form->setConstants(array('sec_token' => $token));
1135
        // Display the form.
1136
        $form->display();
1137
    }
1138
}
1139
1140
/**
1141
 * Delete a template
1142
 *
1143
 * @param integer $id the id of the template that has to be deleted
1144
 *
1145
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
1146
 * @version August 2008
1147
 * @since v1.8.6
1148
 */
1149
function deleteTemplate($id)
1150
{
1151
    // First we remove the image.
1152
    $table_system_template = Database :: get_main_table('system_template');
1153
    $sql = "SELECT * FROM $table_system_template WHERE id = ".intval($id)."";
1154
    $result = Database::query($sql);
1155
    $row = Database::fetch_array($result);
1156
    if (!empty($row['image'])) {
1157
        @unlink(api_get_path(SYS_APP_PATH).'home/default_platform_document/template_thumb/'.$row['image']);
1158
    }
1159
1160
    // Now we remove it from the database.
1161
    $sql = "DELETE FROM $table_system_template WHERE id = ".intval($id)."";
1162
    Database::query($sql);
1163
1164
    // Display a feedback message.
1165
    Display::display_confirmation_message(get_lang('TemplateDeleted'));
1166
}
1167
1168
/**
1169
 * Returns the list of timezone identifiers used to populate the select
1170
 * This function is called through a call_user_func() in the generate_settings_form function.
1171
 * @return array List of timezone identifiers
1172
 *
1173
 * @author Guillaume Viguier <[email protected]>
1174
 * @since Chamilo 1.8.7
1175
 */
1176
function select_timezone_value()
1177
{
1178
    return api_get_timezones();
1179
}
1180
1181
/**
1182
 * Returns an array containing the list of options used to populate the gradebook_number_decimals variable
1183
 * This function is called through a call_user_func() in the generate_settings_form function.
1184
 * @return array List of gradebook_number_decimals options
1185
 *
1186
 * @author Guillaume Viguier <[email protected]>
1187
 */
1188
function select_gradebook_number_decimals() {
1189
    return array('0', '1', '2');
1190
}
1191
1192
/**
1193
 * Get the options for a select element to select gradebook default grade model
1194
 * @return array
1195
 */
1196
function select_gradebook_default_grade_model_id()
1197
{
1198
    $grade_model = new GradeModel();
1199
    $models = $grade_model->get_all();
1200
    $options = array();
1201
    $options[-1] = get_lang('None');
1202
    if (!empty($models)) {
1203
        foreach ($models as $model) {
1204
            $options[$model['id']] = $model['name'];
1205
        }
1206
    }
1207
    return $options;
1208
}
1209
1210
/**
1211
 * @param array $settings
1212
 * @param array $settings_by_access_list
1213
 *
1214
 * @return FormValidator
1215
 *
1216
 * @throws \Doctrine\ORM\ORMException
1217
 * @throws \Doctrine\ORM\OptimisticLockException
1218
 * @throws \Doctrine\ORM\TransactionRequiredException
1219
 */
1220
function generateSettingsForm($settings, $settings_by_access_list)
1221
{
1222
    global $_configuration, $settings_to_avoid, $convert_byte_to_mega_list;
1223
    $em = Database::getManager();
1224
    $table_settings_current = Database :: get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
1225
1226
    $form = new FormValidator('settings', 'post', 'settings.php?category='.Security::remove_XSS($_GET['category']));
1227
1228
    $form->addElement(
1229
        'hidden',
1230
        'search_field',
1231
        (!empty($_GET['search_field']) ? Security::remove_XSS($_GET['search_field']) : null)
1232
    );
1233
1234
    $url_id = api_get_current_access_url_id();
1235
1236
    /*
1237
    if (!empty($_configuration['multiple_access_urls']) && api_is_global_platform_admin() && $url_id == 1) {
1238
        $group = array();
1239
        $group[] = $form->createElement('button', 'mark_all', get_lang('MarkAll'));
1240
        $group[] = $form->createElement('button', 'unmark_all', get_lang('UnmarkAll'));
1241
        $form->addGroup($group, 'buttons_in_action_right');
1242
    }*/
1243
1244
    $default_values = array();
1245
    $url_info = api_get_access_url($url_id);
1246
    $i = 0;
1247
    $addedSettings = [];
1248
    foreach ($settings as $row) {
1249
        if (in_array($row['variable'], array_keys($settings_to_avoid))) {
1250
            continue;
1251
        }
1252
1253
        if (in_array($row['variable'], $addedSettings)) {
1254
            continue;
1255
        }
1256
1257
        $addedSettings[] = $row['variable'];
1258
1259
        if (!empty($_configuration['multiple_access_urls'])) {
1260
            if (api_is_global_platform_admin()) {
1261
                if ($row['access_url_locked'] == 0) {
1262
                    if ($url_id == 1) {
1263
                        if ($row['access_url_changeable'] == '1') {
1264
                            $form->addElement(
1265
                                'html',
1266
                                '<div class="pull-right"><a class="share_this_setting" data_status = "0"  data_to_send = "'.$row['variable'].'" href="javascript:void(0);">'.
1267
                                Display::return_icon('shared_setting.png', get_lang('ChangeSharedSetting') , null, ICON_SIZE_MEDIUM).'</a></div>'
1268
                            );
1269
                        } else {
1270
                            $form->addElement(
1271
                                'html',
1272
                                '<div class="pull-right"><a class="share_this_setting" data_status = "1" data_to_send = "'.$row['variable'].'" href="javascript:void(0);">'.
1273
                                Display::return_icon('shared_setting_na.png', get_lang('ChangeSharedSetting'), null, ICON_SIZE_MEDIUM ).'</a></div>'
1274
                            );
1275
                        }
1276
                    } else {
1277
                        if ($row['access_url_changeable'] == '1') {
1278
                            $form->addElement(
1279
                                'html',
1280
                                '<div class="pull-right">'.
1281
                                Display::return_icon('shared_setting.png', get_lang('ChangeSharedSetting'), null, ICON_SIZE_MEDIUM ).'</div>'
1282
                            );
1283
                        } else {
1284
                            $form->addElement(
1285
                                'html',
1286
                                '<div class="pull-right">'.
1287
                                Display::return_icon('shared_setting_na.png', get_lang('ChangeSharedSetting'), null, ICON_SIZE_MEDIUM ).'</div>'
1288
                            );
1289
                        }
1290
                    }
1291
                }
1292
            }
1293
        }
1294
1295
        $hideme = array();
1296
        $hide_element = false;
1297
1298
        if ($_configuration['access_url'] != 1) {
1299
            if ($row['access_url_changeable'] == 0) {
1300
                // We hide the element in other cases (checkbox, radiobutton) we 'freeze' the element.
1301
                $hide_element = true;
1302
                $hideme = array('disabled');
1303
            } elseif ($url_info['active'] == 1) {
1304
                // We show the elements.
1305
                if (empty($row['variable'])) {
1306
                    $row['variable'] = 0;
1307
                }
1308
                if (empty($row['subkey'])) {
1309
                    $row['subkey'] = 0;
1310
                }
1311
                if (empty($row['category'])) {
1312
                    $row['category'] = 0;
1313
                }
1314
                if (isset($settings_by_access_list[$row['variable']]) &&
1315
                    is_array($settings_by_access_list[$row['variable']][$row['subkey']][$row['category']])) {
1316
1317
                    if ($settings_by_access_list[$row['variable']][$row['subkey']][$row['category']]['selected_value'] != '') {
1318
                        $row['selected_value'] = $settings_by_access_list[$row['variable']] [$row['subkey']] [$row['category']]['selected_value'];
1319
                    }
1320
                }
1321
                // There is no else{} statement because we load the default $row['selected_value'] of the main Chamilo site.
1322
            }
1323
        }
1324
1325
        switch ($row['type']) {
1326
            case 'textfield':
1327
                if (in_array($row['variable'], $convert_byte_to_mega_list)) {
1328
                    $form->addElement(
1329
                        'text',
1330
                        $row['variable'],
1331
                        array(
1332
                            get_lang($row['title']),
1333
                            get_lang($row['comment']),
1334
                            get_lang('MB')
1335
                        ),
1336
                        array('maxlength' => '8')
1337
                    );
1338
                    $form->applyFilter($row['variable'], 'html_filter');
1339
                    $default_values[$row['variable']] = round($row['selected_value']/1024/1024, 1);
1340
                } elseif ($row['variable'] == 'account_valid_duration') {
1341
                    $form->addElement(
1342
                        'text',
1343
                        $row['variable'],
1344
                        array(
1345
                            get_lang($row['title']),
1346
                            get_lang($row['comment']),
1347
                        ),
1348
                        array('maxlength' => '5')
1349
                    );
1350
                    $form->applyFilter($row['variable'], 'html_filter');
1351
                    $default_values[$row['variable']] = $row['selected_value'];
1352
1353
                    // For platform character set selection: Conversion of the textfield to a select box with valid values.
1354
                } elseif ($row['variable'] == 'platform_charset') {
1355
                    continue;
1356
                } else {
1357
                    $hideme['class'] = 'col-md-4';
1358
                    $form->addElement(
1359
                        'text',
1360
                        $row['variable'],
1361
                        array(
1362
                            get_lang($row['title']),
1363
                            get_lang($row['comment'])
1364
                        ),
1365
                        $hideme
1366
                    );
1367
                    $form->applyFilter($row['variable'],'html_filter');
1368
                    $default_values[$row['variable']] = $row['selected_value'];
1369
                }
1370
                break;
1371
            case 'textarea':
1372
                if ($row['variable'] == 'header_extra_content') {
1373
                    $file = api_get_path(SYS_PATH).api_get_home_path().'header_extra_content.txt';
1374
                    $value = '';
1375
                    if (file_exists($file)) {
1376
                        $value = file_get_contents($file);
1377
                    }
1378
                    $form->addElement('textarea', $row['variable'], array(get_lang($row['title']), get_lang($row['comment'])) , array('rows'=>'10'), $hideme);
1379
                    $default_values[$row['variable']] = $value;
1380
                } elseif ($row['variable'] == 'footer_extra_content') {
1381
                    $file = api_get_path(SYS_PATH).api_get_home_path().'footer_extra_content.txt';
1382
                    $value = '';
1383
                    if (file_exists($file)) {
1384
                        $value = file_get_contents($file);
1385
                    }
1386
                    $form->addElement('textarea', $row['variable'], array(get_lang($row['title']), get_lang($row['comment'])) , array('rows'=>'10'), $hideme);
1387
                    $default_values[$row['variable']] = $value;
1388
                } else {
1389
                    $form->addElement('textarea', $row['variable'], array(get_lang($row['title']), get_lang($row['comment'])) , array('rows'=>'10'), $hideme);
1390
                    $default_values[$row['variable']] = $row['selected_value'];
1391
                }
1392
                break;
1393
            case 'radio':
1394
                $values = api_get_settings_options($row['variable']);
1395
                $group = array ();
1396 View Code Duplication
                if (is_array($values)) {
1397
                    foreach ($values as $key => $value) {
1398
                        $element = &$form->createElement(
1399
                            'radio',
1400
                            $row['variable'],
1401
                            '',
1402
                            get_lang($value['display_text']),
1403
                            $value['value']
1404
                        );
1405
                        if ($hide_element) {
1406
                            $element->freeze();
1407
                        }
1408
                        $group[] = $element;
1409
                    }
1410
                }
1411
                $form->addGroup(
1412
                    $group,
1413
                    $row['variable'],
1414
                    array(get_lang($row['title']), get_lang($row['comment'])),
1415
                    null,
1416
                    false
1417
                );
1418
                $default_values[$row['variable']] = $row['selected_value'];
1419
                break;
1420
            case 'checkbox':
1421
                // 1. We collect all the options of this variable.
1422
                $sql = "SELECT * FROM $table_settings_current
1423
                        WHERE variable='".$row['variable']."' AND access_url =  1";
1424
1425
                $result = Database::query($sql);
1426
                $group = array ();
1427
                while ($rowkeys = Database::fetch_array($result)) {
1428
                    // Profile tab option should be hidden when the social tool is enabled.
1429
                    if (api_get_setting('social.allow_social_tool') == 'true') {
1430
                        if ($rowkeys['variable'] == 'show_tabs' && $rowkeys['subkey'] == 'my_profile') {
1431
                            continue;
1432
                        }
1433
                    }
1434
1435
                    // Hiding the gradebook option.
1436
                    if ($rowkeys['variable'] == 'show_tabs' && $rowkeys['subkey'] == 'my_gradebook') {
1437
                        continue;
1438
                    }
1439
1440
                    $element = &$form->createElement(
1441
                        'checkbox',
1442
                        $rowkeys['subkey'],
1443
                        '',
1444
                        get_lang($rowkeys['subkeytext'])
1445
                    );
1446
1447
                    if ($row['access_url_changeable'] == 1) {
1448
                        // 2. We look into the DB if there is a setting for a specific access_url.
1449
                        $access_url = $_configuration['access_url'];
1450
                        if (empty($access_url)) {
1451
                            $access_url = 1;
1452
                        }
1453
                        $sql = "SELECT selected_value FROM $table_settings_current
1454
                                WHERE
1455
                                    variable='".$rowkeys['variable']."' AND
1456
                                    subkey='".$rowkeys['subkey']."' AND
1457
                                    subkeytext='".$rowkeys['subkeytext']."' AND
1458
                                    access_url =  $access_url";
1459
                        $result_access = Database::query($sql);
1460
                        $row_access = Database::fetch_array($result_access);
1461
                        if ($row_access['selected_value'] === 'true' && !$form->isSubmitted()) {
1462
                            $element->setChecked(true);
1463
                        }
1464
                    } else {
1465
                        if ($rowkeys['selected_value'] === 'true' && !$form->isSubmitted()) {
1466
                            $element->setChecked(true);
1467
                        }
1468
                    }
1469
                    if ($hide_element) {
1470
                        $element->freeze();
1471
                    }
1472
                    $group[] = $element;
1473
                }
1474
                $form->addGroup(
1475
                    $group,
1476
                    $row['variable'],
1477
                    array(get_lang($row['title']), get_lang($row['comment'])),
1478
                    null
1479
                );
1480
                break;
1481
            case 'link':
1482
                $form->addElement('static', null, array(get_lang($row['title']), get_lang($row['comment'])),
1483
                    get_lang('CurrentValue') . ' : ' . $row['selected_value'], $hideme);
1484
                break;
1485
            case 'select':
1486
                /*
1487
                * 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.
1488
                * The functions being called must be added to the file settings.lib.php.
1489
                */
1490
                $form->addElement(
1491
                    'select',
1492
                    $row['variable'],
1493
                    array(get_lang($row['title']), get_lang($row['comment'])),
1494
                    call_user_func('select_'.$row['variable']),
1495
                    $hideme
1496
                );
1497
                $default_values[$row['variable']] = $row['selected_value'];
1498
                break;
1499
            case 'custom':
1500
                break;
1501
            case 'select_course':
1502
                $courseSelectOptions = [];
1503
1504
                if (!empty($row['selected_value'])) {
1505
                    $course = $em->find('ChamiloCoreBundle:Course', $row['selected_value']);
1506
1507
                    $courseSelectOptions[$course->getId()] = $course->getTitle();
1508
                }
1509
1510
                $form->addElement(
1511
                    'select_ajax',
1512
                    $row['variable'],
1513
                    [get_lang($row['title']), get_lang($row['comment'])],
1514
                    $courseSelectOptions,
1515
                    ['url' => api_get_path(WEB_AJAX_PATH) . 'course.ajax.php?a=search_course']
1516
                );
1517
                $default_values[$row['variable']] = $row['selected_value'];
1518
                break;
1519
        }
1520
1521
        switch ($row['variable']) {
1522
            case 'pdf_export_watermark_enable':
1523
                $url =  PDF::get_watermark(null);
1524
1525
                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...
1526
                    $delete_url = '<a href="?delete_watermark">'.get_lang('DelImage').' '.Display::return_icon('delete.png',get_lang('DelImage')).'</a>';
1527
                    $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>');
1528
                }
1529
1530
                $form->addElement('file', 'pdf_export_watermark_path', get_lang('AddWaterMark'));
1531
                $allowed_picture_types = array('jpg', 'jpeg', 'png', 'gif');
1532
                $form->addRule('pdf_export_watermark_path', get_lang('OnlyImagesAllowed').' ('.implode(',', $allowed_picture_types).')', 'filetype', $allowed_picture_types);
1533
1534
                break;
1535
            case 'timezone_value':
1536
                $timezone = $row['selected_value'];
1537
                if (empty($timezone)) {
1538
                    $timezone = api_get_timezone();
1539
                }
1540
                $form->addLabel('', sprintf(get_lang('LocalTimeUsingPortalTimezoneXIsY'), $timezone, api_get_local_time()));
1541
                break;
1542
        }
1543
    } // end for
1544
1545
    if (!empty($settings)) {
1546
        $form->setDefaults($default_values);
1547
    }
1548
    $form->addHtml('<div class="bottom_actions">');
1549
    $form->addButtonSave(get_lang('SaveSettings'));
1550
    $form->addHtml('</div>');
1551
    return $form;
1552
}
1553
1554
/**
1555
 * Searches a platform setting in all categories except from the Plugins category
1556
 * @param string $search
1557
 * @return array
1558
 */
1559
function searchSetting($search)
1560
{
1561
    if (empty($search)) {
1562
        return array();
1563
    }
1564
    $table_settings_current = Database :: get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
1565
    $sql = "SELECT * FROM $table_settings_current
1566
            WHERE category <> 'Plugins' ORDER BY id ASC ";
1567
    $result = Database::store_result(Database::query($sql), 'ASSOC');
0 ignored issues
show
Bug introduced by
It seems like \Database::query($sql) can be null; however, store_result() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1568
    $settings = array();
1569
1570
    $search = api_strtolower($search);
1571
1572
    if (!empty($result)) {
1573
        foreach ($result as $setting) {
1574
            $found = false;
1575
1576
            $title = api_strtolower(get_lang($setting['title']));
1577
            // try the title
1578
            if (strpos($title, $search) === false) {
1579
                $comment = api_strtolower(get_lang($setting['comment']));
1580
                //Try the comment
1581
                if (strpos($comment, $search) === false) {
1582
                    //Try the variable name
1583
                    if (strpos($setting['variable'], $search) === false) {
1584
                        continue;
1585
                    } else {
1586
                        $found = true;
1587
                    }
1588
                } else {
1589
                    $found = true;
1590
                }
1591
1592
            } else {
1593
                $found = true;
1594
            }
1595
            if ($found) {
1596
                $settings[] = $setting;
1597
            }
1598
        }
1599
    }
1600
    return $settings;
1601
}
1602
/**
1603
 * Helper function to generates a form elements group
1604
 * @param object $form The form where the elements group has to be added
1605
 * @param array $values Values to browse through
1606
 * @return array
1607
 */
1608
function formGenerateElementsGroup($form, $values = array(), $elementName)
1609
{
1610
    $group = array();
1611 View Code Duplication
    if (is_array($values)) {
1612
        foreach ($values as $key => $value) {
1613
            $element = &$form->createElement('radio', $elementName, '', get_lang($value['display_text']), $value['value']);
1614
            $group[] = $element;
1615
        }
1616
    }
1617
    return $group;
1618
}
1619
/**
1620
 * Helper function with allowed file types for CSS
1621
 * @return  array Array of file types (no indexes)
1622
 */
1623
function getAllowedFileTypes()
1624
{
1625
    $allowedFiles = array(
1626
        'css',
1627
        'zip',
1628
        'jpeg',
1629
        'jpg',
1630
        'png',
1631
        'gif',
1632
        'ico',
1633
        'psd',
1634
        'xcf',
1635
        'svg',
1636
        'webp',
1637
        'woff',
1638
        'woff2'
1639
    );
1640
    return $allowedFiles;
1641
}
1642
/**
1643
 * Helper function to set settings in the database
1644
 * @param   array   $parameters     List of values
1645
 * @param   int     $accessUrl      The current access URL
1646
 * @return  void
1647
 */
1648
function setConfigurationSettingsInDatabase($parameters, $accessUrl)
1649
{
1650
    $r = api_set_settings_category('Search', 'false', $accessUrl);
1651
    // Save the settings.
1652
    foreach ($parameters as $key => $value) {
1653
        $result = api_set_setting($key, $value, null, null);
1654
    }
1655
}
1656
1657
/**
1658
 * Helper function to show the status of the search settings table
1659
 * @param   array   $data   Data to show
1660
 * @return void
1661
 */
1662
function showSearchSettingsTable($data)
1663
{
1664
    echo Display::tag('h3', get_lang('Settings'));
1665
    $table = new SortableTableFromArray($data);
1666
    $table->set_header(0, get_lang('Setting'), false);
1667
    $table->set_header(1, get_lang('Status'), false);
1668
    echo $table->display();
1669
}
1670
/**
1671
 * Helper function to show status table for each command line tool installed
1672
 * @return void
1673
 */
1674
function showSearchToolsStatusTable()
1675
{
1676
    //@todo windows support
1677
    if (api_is_windows_os() == false) {
1678
        $list_of_programs = array('pdftotext', 'ps2pdf', 'catdoc', 'html2text', 'unrtf', 'catppt', 'xls2csv');
1679
1680
        foreach($list_of_programs as $program) {
1681
            $output = [];
1682
            $ret_val = null;
1683
            exec("which $program", $output, $ret_val);
1684
1685
            if (!$output) {
1686
                $output[] = '';
1687
            }
1688
1689
            $icon = Display::return_icon('bullet_red.png', get_lang('NotInstalled'));
1690
            if (!empty($output[0])) {
1691
                $icon = Display::return_icon('bullet_green.png', get_lang('Installed'));
1692
            }
1693
            $data2[]= array($program, $output[0], $icon);
1694
        }
1695
        echo Display::tag('h3', get_lang('ProgramsNeededToConvertFiles'));
1696
        $table = new SortableTableFromArray($data2);
1697
        $table->set_header(0, get_lang('Program'), false);
1698
        $table->set_header(1, get_lang('Path'), false);
1699
        $table->set_header(2, get_lang('Status'), false);
1700
        echo $table->display();
1701
    } else {
1702
        Display::display_warning_message(
1703
            get_lang('YouAreUsingChamiloInAWindowsPlatformSadlyYouCantConvertDocumentsInOrderToSearchTheContentUsingThisTool')
1704
        );
1705
    }
1706
}
1707
/**
1708
 * Helper function to generate and show CSS Zip download message
1709
 * @param   string $style Style path
1710
 * @return void
1711
 */
1712
function generateCSSDownloadLink($style)
1713
{
1714
    $arch = api_get_path(SYS_ARCHIVE_PATH).$style.'.zip';
1715
    $dir = api_get_path(SYS_CSS_PATH).'themes/'.$style;
1716
    if (is_dir($dir)) {
1717
        $zip = new PclZip($arch);
1718
        // Remove path prefix except the style name and put file on disk
1719
        $zip->create($dir, PCLZIP_OPT_REMOVE_PATH, substr($dir,0,-strlen($style)));
1720
        //@TODO: use more generic script to download.
1721
        $str = '<a class="btn btn-primary btn-large" href="' . api_get_path(WEB_CODE_PATH) . 'course_info/download.php?archive=' . str_replace(api_get_path(SYS_ARCHIVE_PATH), '', $arch) . '">'.get_lang('ClickHereToDownloadTheFile').'</a>';
1722
        Display::display_normal_message($str, false);
1723
    } else {
1724
        Display::addFlash(Display::return_message(get_lang('FileNotFound'), 'warning'));
1725
    }
1726
}
1727
/**
1728
 * Helper function to tell if the style is changeable in the current URL
1729
 * @return bool $changeable Whether the style can be changed in this URL or not
1730
 */
1731
function isStyleChangeable() {
1732
    global $_configuration;
1733
    $changeable = false;
1734
    if ($_configuration['access_url'] != 1) {
1735
        $style_info = api_get_settings('stylesheets', '', 1, 0);
1736
        $url_info = api_get_access_url($_configuration['access_url']);
1737
        if ($style_info[0]['access_url_changeable'] == 1 && $url_info['active'] == 1) {
1738
            $changeable = true;
1739
        }
1740
    } else {
1741
        $changeable = true;
1742
    }
1743
    return $changeable;
1744
}
1745