Completed
Push — 1.10.x ( fe0e5a...3a6f9c )
by Yannick
134:15 queued 86:39
created

Display   F

Complexity

Total Complexity 374

Size/Duplication

Total Lines 2459
Duplicated Lines 5.69 %

Coupling/Cohesion

Components 3
Dependencies 15

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 140
loc 2459
rs 0.6314
wmc 374
lcom 3
cbo 15

80 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A toolList() 0 14 1
D display_header() 0 41 9
A display_reduced_header() 0 6 1
A display_no_header() 0 6 1
A set_header() 0 5 1
A display_footer() 0 4 1
A page() 0 4 1
A display_introduction_section() 0 4 1
A return_introduction_section() 0 10 3
A display_localised_html_file() 0 11 2
C display_sortable_table() 0 34 12
A return_sortable_table() 0 23 1
A display_sortable_grid() 0 23 1
B return_sortable_grid() 0 29 3
C display_sortable_config_table() 0 41 11
A display_normal_message() 9 9 2
A display_warning_message() 9 9 2
A display_confirmation_message() 9 9 2
A display_error_message() 9 9 2
A return_message_and_translate() 0 5 1
A display_reduced_footer() 0 4 1
C encrypted_mailto_link() 4 32 7
B icon_mailto_link() 4 22 4
A get_platform_home_link_html() 0 7 2
A get_alphabet_options() 13 13 3
A get_numeric_options() 13 13 4
A display_icon() 0 8 1
A tabsOnlyLink() 0 20 3
A grid_html() 0 6 1
A form_row() 0 6 1
F grid_js() 0 141 18
B table() 0 27 6
F show_notification() 0 164 31
D get_session_title_box() 23 145 22
F return_rating_system() 0 44 12
A return_default_table_class() 0 4 1
A page_header() 0 14 4
A page_header_and_translate() 0 5 1
A page_subheader_and_translate() 0 5 1
A page_subheader() 0 8 2
A page_subheader2() 0 4 1
A page_subheader3() 0 4 1
A description() 0 13 3
A bar_progress() 0 23 3
C badge() 0 27 7
A badge_group() 0 9 2
C label() 0 34 8
C actions() 0 23 7
A tip() 0 7 2
B generate_accordion() 0 33 5
A group_button() 0 14 2
D getMediaPlayer() 0 34 10
B img() 0 23 5
B tag() 0 18 5
A url() 0 9 2
A div() 0 4 1
A span() 0 4 1
A input() 0 13 4
A button() 0 7 2
C select() 0 53 13
C tabs() 0 41 7
D return_message() 0 30 10
A returnIconPath() 0 4 1
A addFlash() 0 10 2
A getFlashToString() 0 12 3
A showFlash() 0 4 1
A cleanFlashMessages() 0 4 1
B getProfileEditionLink() 7 29 4
A getVCardUserLink() 0 6 1
A panel() 0 15 4
A contentPanel() 0 6 1
A toolbarButton() 0 18 3
C toolbarAction() 0 30 7
C returnFontAwesomeIcon() 0 35 8
C panelCollapse() 12 46 8
C progressPaginationBar() 0 49 10
F parsePaginationItem() 18 58 16
A paginationIndicator() 0 9 3
F return_icon() 10 83 16

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Display often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Display, and based on these observations, apply Extract Interface, too.

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use ChamiloSession as Session;
5
6
/**
7
 * Class Display
8
 * Contains several public functions dealing with the display of
9
 * table data, messages, help topics, ...
10
 *
11
 * Include/require it in your code to use its public functionality.
12
 * There are also several display public functions in the main api library.
13
 *
14
 * All public functions static public functions inside a class called Display,
15
 * so you use them like this: e.g.
16
 * Display::display_normal_message($message)
17
 *
18
 * @package chamilo.library
19
 *
20
 */
21
class Display
22
{
23
    /** @var Template */
24
    public static $global_template;
25
    public static $preview_style = null;
26
27
    /**
28
     * Constructor
29
     */
30
    public function __construct()
31
    {
32
    }
33
34
    /**
35
     * @return array
36
     */
37
    public static function toolList()
38
    {
39
        return array(
40
            'group',
41
            'work',
42
            'glossary',
43
            'forum',
44
            'course_description',
45
            'gradebook',
46
            'attendance',
47
            'course_progress',
48
            'notebook'
49
        );
50
    }
51
52
     /**
53
     * Displays the page header
54
     * @param string The name of the page (will be showed in the page title)
55
     * @param string Optional help file name
56
     * @param string $page_header
57
     */
58
    public static function display_header($tool_name ='', $help = null, $page_header = null)
59
    {
60
        $origin = api_get_origin();
61
        $showHeader = true;
62
        if (isset($origin) && $origin == 'learnpath') {
63
            $showHeader = false;
64
        }
65
66
        self::$global_template = new Template($tool_name, $showHeader, $showHeader);
67
68
        // Fixing tools with any help it takes xxx part of main/xxx/index.php
69
        if (empty($help)) {
70
            $currentURL = api_get_self();
71
            preg_match('/main\/([^*\/]+)/', $currentURL, $matches);
72
            $toolList = self::toolList();
73
            if (!empty($matches)) {
74
                foreach ($matches as $match) {
75
                    if (in_array($match, $toolList)) {
76
                        $help = explode('_', $match);
77
                        $help = array_map('ucfirst', $help);
78
                        $help = implode('', $help);
79
                        break;
80
                    }
81
                }
82
            }
83
        }
84
85
        self::$global_template->setHelp($help);
86
87
        if (!empty(self::$preview_style)) {
88
            self::$global_template->preview_theme = self::$preview_style;
89
            self::$global_template->setCssFiles();
90
            self::$global_template->set_js_files();
91
            self::$global_template->setCssCustomFiles();
92
        }
93
        if (!empty($page_header)) {
94
            self::$global_template->assign('header', $page_header);
95
        }
96
97
        echo self::$global_template->show_header_template();
98
    }
99
100
    /**
101
     * Displays the reduced page header (without banner)
102
     */
103
    public static function display_reduced_header()
104
    {
105
        global $show_learnpath, $tool_name;
106
        self::$global_template = new Template($tool_name, false, false, $show_learnpath);
107
        echo self::$global_template->show_header_template();
108
    }
109
110
    /**
111
     * Display no header
112
     */
113
    public static function display_no_header()
114
    {
115
        global $tool_name, $show_learnpath;
116
        $disable_js_and_css_files = true;
117
        self::$global_template = new Template($tool_name, false, false, $show_learnpath);
118
    }
119
120
    /**
121
     * Displays the reduced page header (without banner)
122
     */
123
    public static function set_header()
124
    {
125
        global $show_learnpath, $tool_name;
126
        self::$global_template = new Template($tool_name, false, false, $show_learnpath);
127
    }
128
129
    /**
130
     * Display the page footer
131
     */
132
    public static function display_footer()
133
    {
134
        echo self::$global_template->show_footer_template();
135
    }
136
137
    /**
138
     * Display the page footer
139
     */
140
    public static function display_reduced_footer()
141
    {
142
        echo self::$global_template->show_footer_js_template();
143
    }
144
145
    public static function page()
146
    {
147
        return new Page();
148
    }
149
150
    /**
151
     * Displays the tool introduction of a tool.
152
     *
153
     * @author Patrick Cool <[email protected]>, Ghent University
154
     * @param string $tool These are the constants that are used for indicating the tools.
155
     * @param array $editor_config Optional configuration settings for the online editor.
156
     * return: $tool return a string array list with the "define" in main_api.lib
157
     * @return html code for adding an introduction
158
     */
159
    public static function display_introduction_section($tool, $editor_config = null)
160
    {
161
        echo self::return_introduction_section($tool, $editor_config);
162
    }
163
164
    /**
165
     * @param string $tool
166
     * @param array $editor_config
167
     * @return null
168
     */
169
    public static function return_introduction_section($tool, $editor_config = null)
170
    {
171
        $is_allowed_to_edit = api_is_allowed_to_edit();
172
        $moduleId = $tool;
173
        if (api_get_setting('enable_tool_introduction') == 'true' || $tool == TOOL_COURSE_HOMEPAGE) {
174
            $introduction_section = null;
175
            require api_get_path(INCLUDE_PATH).'introductionSection.inc.php';
176
            return $introduction_section;
177
        }
178
    }
179
180
    /**
181
     *	Displays a localised html file
182
     *	tries to show the file "$full_file_name"."_".$language_interface.".html"
183
     *	and if this does not exist, shows the file "$full_file_name".".html"
184
     *	warning this public function defines a global
185
     *	@param $full_file_name, the (path) name of the file, without .html
186
     *	@return return a string with the path
187
     */
188
    public static function display_localised_html_file($full_file_name)
189
    {
190
        global $language_interface;
191
        $localised_file_name = $full_file_name.'_'.$language_interface.'.html';
192
        $default_file_name = $full_file_name.'.html';
193
        if (file_exists($localised_file_name)) {
194
            include $localised_file_name;
195
        } else {
196
            include $default_file_name;
197
        }
198
    }
199
200
    /**
201
     * Displays a table
202
     * @param array $header Titles for the table header
203
     * 						each item in this array can contain 3 values
204
     * 						- 1st element: the column title
205
     * 						- 2nd element: true or false (column sortable?)
206
     * 						- 3th element: additional attributes for
207
     *  						th-tag (eg for column-width)
208
     * 						- 4the element: additional attributes for the td-tags
209
     * @param array $content 2D-array with the tables content
210
     * @param array $sorting_options Keys are:
211
     * 					'column' = The column to use as sort-key
212
     * 					'direction' = SORT_ASC or SORT_DESC
213
     * @param array $paging_options Keys are:
214
     * 					'per_page_default' = items per page when switching from
215
     * 										 full-	list to per-page-view
216
     * 					'per_page' = number of items to show per page
217
     * 					'page_nr' = The page to display
218
     * @param array $query_vars Additional variables to add in the query-string
219
     * @param string The style that the table will show. You can set 'table' or 'grid'
220
     * @author [email protected]
221
     */
222
    public static function display_sortable_table(
223
        $header,
224
        $content,
225
        $sorting_options = array(),
226
        $paging_options = array(),
227
        $query_vars = null,
228
        $form_actions = array(),
229
        $style = 'table'
230
    ) {
231
        global $origin;
232
        $column = isset($sorting_options['column']) ? $sorting_options['column'] : 0;
233
        $default_items_per_page = isset($paging_options['per_page']) ? $paging_options['per_page'] : 20;
234
        $table = new SortableTableFromArray($content, $column, $default_items_per_page);
235
        if (is_array($query_vars)) {
236
            $table->set_additional_parameters($query_vars);
237
        }
238
        if ($style == 'table') {
239
            if (is_array($header) && count($header) > 0) {
240
                foreach ($header as $index => $header_item) {
241
                    $table->set_header(
242
                        $index,
243
                        isset($header_item[0]) ? $header_item[0] : null,
244
                        isset($header_item[1]) ? $header_item[1] : null,
245
                        isset($header_item[2]) ? $header_item[2] : null,
246
                        isset($header_item[3]) ? $header_item[3] : null
247
                    );
248
                }
249
            }
250
            $table->set_form_actions($form_actions);
251
            $table->display();
252
        } else {
253
            $table->display_grid();
254
        }
255
    }
256
257
    public static function return_sortable_table(
258
        $header,
259
        $content,
260
        $sorting_options = array(),
261
        $paging_options = array(),
262
        $query_vars = null,
263
        $form_actions = array(),
264
        $style = 'table'
265
    ) {
266
        ob_start();
267
        self::display_sortable_table(
268
            $header,
269
            $content,
270
            $sorting_options,
271
            $paging_options,
272
            $query_vars,
273
            $form_actions,
274
            $style
275
        );
276
        $content = ob_get_contents();
277
        ob_end_clean();
278
        return $content;
279
    }
280
281
    /**
282
     * Shows a nice grid
283
     * @param string grid name (important to create css)
284
     * @param array header content
285
     * @param array array with the information to show
286
     * @param array $paging_options Keys are:
287
     * 					'per_page_default' = items per page when switching from
288
     * 										 full-	list to per-page-view
289
     * 					'per_page' = number of items to show per page
290
     * 					'page_nr' = The page to display
291
     * 					'hide_navigation' =  true to hide the navigation
292
     * @param array $query_vars Additional variables to add in the query-string
293
     * @param array $form actions Additional variables to add in the query-string
0 ignored issues
show
Bug introduced by
There is no parameter named $form. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
294
     * @param mixed An array with bool values to know which columns show.
295
     * i.e: $visibility_options= array(true, false) we will only show the first column
296
     * 				Can be also only a bool value. TRUE: show all columns, FALSE: show nothing
297
     */
298
    public static function display_sortable_grid(
299
        $name,
300
        $header,
301
        $content,
302
        $paging_options = array(),
303
        $query_vars = null,
304
        $form_actions = array(),
305
        $visibility_options = true,
306
        $sort_data = true,
307
        $grid_class = array()
308
    ) {
309
        echo self::return_sortable_grid(
310
            $name,
311
            $header,
312
            $content,
313
            $paging_options,
314
            $query_vars,
315
            $form_actions,
316
            $visibility_options,
317
            $sort_data,
318
            $grid_class
319
        );
320
    }
321
322
    /**
323
     * Gets a nice grid in html string
324
     * @param string grid name (important to create css)
325
     * @param array header content
326
     * @param array array with the information to show
327
     * @param array $paging_options Keys are:
328
     * 					'per_page_default' = items per page when switching from
329
     * 										 full-	list to per-page-view
330
     * 					'per_page' = number of items to show per page
331
     * 					'page_nr' = The page to display
332
     * 					'hide_navigation' =  true to hide the navigation
333
     * @param array $query_vars Additional variables to add in the query-string
334
     * @param array $form actions Additional variables to add in the query-string
0 ignored issues
show
Bug introduced by
There is no parameter named $form. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
335
     * @param mixed An array with bool values to know which columns show. i.e:
336
     *  $visibility_options= array(true, false) we will only show the first column
337
     * 	Can be also only a bool value. TRUE: show all columns, FALSE: show nothing
338
     * @param bool  true for sorting data or false otherwise
339
     * @param array grid classes
340
     * @return 	string   html grid
341
     */
342
    public static function return_sortable_grid(
343
        $name,
344
        $header,
345
        $content,
346
        $paging_options = array(),
347
        $query_vars = null,
348
        $form_actions = array(),
349
        $visibility_options = true,
350
        $sort_data = true,
351
        $grid_class = array(),
352
        $elementCount = 0
353
    ) {
354
        $column =  0;
355
        $default_items_per_page = isset($paging_options['per_page']) ? $paging_options['per_page'] : 20;
356
357
        $table = new SortableTableFromArray($content, $column, $default_items_per_page, $name);
358
        $table->total_number_of_items = intval($elementCount);
359
        if (is_array($query_vars)) {
360
            $table->set_additional_parameters($query_vars);
361
        }
362
363
        return $table->display_simple_grid(
364
            $visibility_options,
365
            $paging_options['hide_navigation'],
366
            $default_items_per_page,
367
            $sort_data,
368
            $grid_class
369
        );
370
    }
371
372
    /**
373
     * Displays a table with a special configuration
374
     * @param array $header Titles for the table header
375
     * 						each item in this array can contain 3 values
376
     * 						- 1st element: the column title
377
     * 						- 2nd element: true or false (column sortable?)
378
     * 						- 3th element: additional attributes for
379
     *  						th-tag (eg for column-width)
380
     * 						- 4the element: additional attributes for the td-tags
381
     * @param array $content 2D-array with the tables content
382
     * @param array $sorting_options Keys are:
383
     * 					'column' = The column to use as sort-key
384
     * 					'direction' = SORT_ASC or SORT_DESC
385
     * @param array $paging_options Keys are:
386
     * 					'per_page_default' = items per page when switching from
387
     * 										 full-	list to per-page-view
388
     * 					'per_page' = number of items to show per page
389
     * 					'page_nr' = The page to display
390
     * @param array $query_vars Additional variables to add in the query-string
391
     * @param array $column_show Array of binaries 1= show columns 0. hide a column
392
     * @param array $column_order An array of integers that let us decide how the columns are going to be sort.
393
     * 						      i.e:  $column_order=array('1''4','3','4'); The 2nd column will be order like the 4th column
394
     * @param array $form_actions Set optional forms actions
395
     *
396
     * @author Julio Montoya
397
     */
398
    public static function display_sortable_config_table(
399
        $table_name,
400
        $header,
401
        $content,
402
        $sorting_options = array(),
403
        $paging_options = array(),
404
        $query_vars = null,
405
        $column_show = array(),
406
        $column_order = array(),
407
        $form_actions = array()
408
    ) {
409
        $column = isset($sorting_options['column']) ? $sorting_options['column'] : 0;
410
        $default_items_per_page = isset($paging_options['per_page']) ? $paging_options['per_page'] : 20;
411
412
        $table = new SortableTableFromArrayConfig(
413
            $content,
414
            $column,
415
            $default_items_per_page,
416
            $table_name,
417
            $column_show,
418
            $column_order
419
        );
420
421
        if (is_array($query_vars)) {
422
            $table->set_additional_parameters($query_vars);
423
        }
424
        // Show or hide the columns header
425
        if (is_array($column_show)) {
426
            for ($i = 0; $i < count($column_show); $i++) {
427
                if (!empty($column_show[$i])) {
428
                    $val0 = isset($header[$i][0]) ? $header[$i][0] : null;
429
                    $val1 = isset($header[$i][1]) ? $header[$i][1] : null;
430
                    $val2 = isset($header[$i][2]) ? $header[$i][2] : null;
431
                    $val3 = isset($header[$i][3]) ? $header[$i][3] : null;
432
                    $table->set_header($i, $val0, $val1, $val2, $val3);
433
                }
434
            }
435
        }
436
        $table->set_form_actions($form_actions);
437
        $table->display();
438
    }
439
440
    /**
441
     * Displays a normal message. It is recommended to use this public function
442
     * to display any normal information messages.
443
     * @param string $message
444
     * @param bool	$filter (true) or not (false)
445
     * @param bool $returnValue
446
     *
447
     * @return void
448
     */
449 View Code Duplication
    public static function display_normal_message($message, $filter = true, $returnValue = false)
450
    {
451
    	$message = self::return_message($message, 'normal', $filter);
452
        if ($returnValue) {
453
            return $message;
454
        } else {
455
            echo $message;
456
        }
457
    }
458
459
    /**
460
     * Displays an warning message. Use this if you want to draw attention to something
461
     * This can also be used for instance with the hint in the exercises
462
     *
463
     */
464 View Code Duplication
    public static function display_warning_message($message, $filter = true, $returnValue = false)
465
    {
466
        $message = self::return_message($message, 'warning', $filter);
467
        if ($returnValue) {
468
            return $message;
469
        } else {
470
            echo $message;
471
        }
472
    }
473
474
    /**
475
     * Displays an confirmation message. Use this if something has been done successfully
476
     * @param bool	Filter (true) or not (false)
477
     * @return void
478
     */
479 View Code Duplication
    public static function display_confirmation_message ($message, $filter = true, $returnValue = false)
480
    {
481
        $message = self::return_message($message, 'confirm', $filter);
482
        if ($returnValue) {
483
            return $message;
484
        } else {
485
            echo $message;
486
        }
487
    }
488
489
    /**
490
     * Displays an error message. It is recommended to use this public function if an error occurs
491
     * @param string $message - include any additional html
492
     *                          tags if you need them
493
     * @param bool	Filter (true) or not (false)
494
     * @return void
495
     */
496 View Code Duplication
    public static function display_error_message ($message, $filter = true, $returnValue = false)
497
    {
498
        $message = self::return_message($message, 'error', $filter);
499
        if ($returnValue) {
500
            return $message;
501
        } else {
502
            echo $message;
503
        }
504
    }
505
506
    /**
507
     * @param string $message
508
     * @param string $type
509
     * @param bool $filter
510
     */
511
    public static function return_message_and_translate($message, $type='normal', $filter = true)
512
    {
513
        $message = get_lang($message);
514
        echo self::return_message($message, $type, $filter);
515
    }
516
517
    /**
518
     * Returns a div html string with
519
     * @param   string  The message
520
     * @param   string  The message type (confirm,normal,warning,error)
521
     * @param   bool    Whether to XSS-filter or not
522
     * @return  string  Message wrapped into an HTML div
523
     */
524
    public static function return_message($message, $type = 'normal', $filter = true)
525
    {
526
        if (empty($message)) {
527
            return '';
528
        }
529
530
        if ($filter) {
531
        	$message = api_htmlentities($message, ENT_QUOTES, api_is_xml_http_request() ? 'UTF-8' : api_get_system_encoding());
532
        }
533
534
        $class = "";
535
        switch($type) {
536
            case 'warning':
537
               $class .= 'alert alert-warning';
538
               break;
539
            case 'error':
540
               $class .= 'alert alert-danger';
541
               break;
542
            case 'confirmation':
543
            case 'confirm':
544
            case 'success':
545
                $class .= 'alert alert-success';
546
               break;
547
            case 'normal':
548
            default:
549
                $class .= 'alert alert-info';
550
        }
551
552
        return self::div($message, array('class'=> $class));
553
    }
554
555
    /**
556
     * Returns an encrypted mailto hyperlink
557
     *
558
     * @param string  e-mail
559
     * @param string  clickable text
560
     * @param string  optional, class from stylesheet
561
     * @return string encrypted mailto hyperlink
562
     */
563
    public static function encrypted_mailto_link ($email, $clickable_text = null, $style_class = '')
564
    {
565
        if (is_null($clickable_text)) {
566
            $clickable_text = $email;
567
        }
568
        // "mailto:" already present?
569
        if (substr($email, 0, 7) != 'mailto:') {
570
            $email = 'mailto:'.$email;
571
        }
572
        // Class (stylesheet) defined?
573
        if ($style_class != '') {
574
            $style_class = ' class="'.$style_class.'"';
575
        }
576
        // Encrypt email
577
        $hmail = '';
578 View Code Duplication
        for ($i = 0; $i < strlen($email); $i ++) {
579
            $hmail .= '&#'.ord($email {
580
            $i }).';';
581
        }
582
        $hclickable_text = null;
583
        // Encrypt clickable text if @ is present
584
        if (strpos($clickable_text, '@')) {
585
            for ($i = 0; $i < strlen($clickable_text); $i ++) {
586
                $hclickable_text .= '&#'.ord($clickable_text {
587
                $i }).';';
588
            }
589
        } else {
590
            $hclickable_text = @htmlspecialchars($clickable_text, ENT_QUOTES, api_get_system_encoding());
591
        }
592
        // Return encrypted mailto hyperlink
593
        return '<a href="'.$hmail.'"'.$style_class.' class="clickable_email_link">'.$hclickable_text.'</a>';
594
    }
595
596
    /**
597
     * Returns an mailto icon hyperlink
598
     *
599
     * @param string  e-mail
600
     * @param string  icon source file from the icon lib
601
     * @param integer  icon size from icon lib
602
     * @param string  optional, class from stylesheet
603
     * @return string encrypted mailto hyperlink
604
     */
605
    public static function icon_mailto_link($email, $icon_file = "mail.png", $icon_size = 22, $style_class = '')
606
    {
607
        // "mailto:" already present?
608
        if (substr($email, 0, 7) != 'mailto:') {
609
            $email = 'mailto:'.$email;
610
        }
611
        // Class (stylesheet) defined?
612
        if ($style_class != '') {
613
            $style_class = ' class="'.$style_class.'"';
614
        }
615
        // Encrypt email
616
        $hmail = '';
617 View Code Duplication
        for ($i = 0; $i < strlen($email); $i ++) {
618
            $hmail .= '&#'.ord($email {
619
            $i }).';';
620
        }
621
        // icon html code
622
        $icon_html_source = self::return_icon($icon_file, $hmail, '', $icon_size);
623
        // Return encrypted mailto hyperlink
624
625
        return '<a href="'.$hmail.'"'.$style_class.' class="clickable_email_link">'.$icon_html_source.'</a>';
626
    }
627
628
    /**
629
     *	Creates a hyperlink to the platform homepage.
630
     *	@param string $name, the visible name of the hyperlink, default is sitename
0 ignored issues
show
Bug introduced by
There is no parameter named $name,. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
631
     *	@return string with html code for hyperlink
632
     */
633
    public static function get_platform_home_link_html($name = '')
634
    {
635
        if ($name == '') {
636
            $name = api_get_setting('siteName');
637
        }
638
        return '<a href="'.api_get_path(WEB_PATH).'index.php">'.$name.'</a>';
639
    }
640
641
    /**
642
     * Prints an <option>-list with all letters (A-Z).
643
     * @param char $selected_letter The letter that should be selected
644
     * @todo This is English language specific implementation.
645
     * It should be adapted for the other languages.
646
     */
647 View Code Duplication
    public static function get_alphabet_options($selected_letter = '')
648
    {
649
        $result = '';
650
        for ($i = 65; $i <= 90; $i ++) {
651
            $letter = chr($i);
652
            $result .= '<option value="'.$letter.'"';
653
            if ($selected_letter == $letter) {
654
                $result .= ' selected="selected"';
655
            }
656
            $result .= '>'.$letter.'</option>';
657
        }
658
        return $result;
659
    }
660
661
    /**
662
     * Get the options withing a select box within the given values
663
     * @param int   Min value
664
     * @param int   Max value
665
     * @param int   Default value
666
     * @return string HTML select options
667
     */
668 View Code Duplication
    public static function get_numeric_options($min, $max, $selected_num = 0)
669
    {
670
        $result = '';
671
        for ($i = $min; $i <= $max; $i ++) {
672
            $result .= '<option value="'.$i.'"';
673
            if (is_int($selected_num))
674
                if ($selected_num == $i) {
675
                    $result .= ' selected="selected"';
676
                }
677
            $result .= '>'.$i.'</option>';
678
        }
679
        return $result;
680
    }
681
682
    /**
683
     * This public function displays an icon
684
     * @param string   The filename of the file (in the main/img/ folder
685
     * @param string   The alt text (probably a language variable)
686
     * @param array    additional attributes (for instance height, width, onclick, ...)
687
     * @param integer  The wanted width of the icon (to be looked for in the corresponding img/icons/ folder)
688
     * @return void
689
    */
690
    public static function display_icon(
691
        $image,
692
        $alt_text = '',
693
        $additional_attributes = array(),
694
        $size = null
695
    ) {
696
        echo self::return_icon($image, $alt_text, $additional_attributes, $size);
697
    }
698
699
    /**
700
     * Gets the path of an icon
701
     *
702
     * @param string $icon
703
     * @param string $size
704
     *
705
     * @return string
706
     */
707
    public static function returnIconPath($icon, $size = ICON_SIZE_SMALL)
708
    {
709
        return Display::return_icon($icon, null, null, $size, null, true, false);
710
    }
711
712
    /**
713
     * This public function returns the htmlcode for an icon
714
     *
715
     * @param string   The filename of the file (in the main/img/ folder
716
     * @param string   The alt text (probably a language variable)
717
     * @param array    Additional attributes (for instance height, width, onclick, ...)
718
     * @param integer  The wanted width of the icon (to be looked for in the corresponding img/icons/ folder)
719
     * @return string  An HTML string of the right <img> tag
720
     *
721
     * @author Patrick Cool <[email protected]>, Ghent University 2006
722
     * @author Julio Montoya 2010 Function improved, adding image constants
723
     * @author Yannick Warnier 2011 Added size handler
724
     * @version Feb 2011
725
    */
726
    public static function return_icon(
727
        $image,
728
        $alt_text = '',
729
        $additional_attributes = array(),
730
        $size = ICON_SIZE_SMALL,
731
        $show_text = true,
732
        $return_only_path = false,
733
        $loadThemeIcon = true
734
    ) {
735
        $code_path = api_get_path(SYS_CODE_PATH);
736
        $w_code_path = api_get_path(WEB_CODE_PATH);
737
        $alternateCssPath = api_get_path(SYS_CSS_PATH);
738
        $alternateWebCssPath = api_get_path(WEB_CSS_PATH);
739
740
        $image = trim($image);
741
742
        if (isset($size)) {
743
            $size = intval($size);
744
        } else {
745
            $size = ICON_SIZE_SMALL;
746
        }
747
748
        $size_extra = $size . '/';
749
750
        // Checking the img/ folder
751
        $icon = $w_code_path.'img/'.$image;
752
753
        $theme = 'themes/chamilo/icons/';
754
755
        if ($loadThemeIcon) {
756
            $theme = 'themes/' . api_get_visual_theme() . '/icons/';
757
            // Checking the theme icons folder example: app/Resources/public/css/themes/chamilo/icons/XXX
758
            if (is_file($alternateCssPath.$theme.$size_extra.$image)) {
759
                $icon = $alternateWebCssPath.$theme.$size_extra.$image;
760 View Code Duplication
            } elseif (is_file($code_path.'img/icons/'.$size_extra.$image)) {
761
                //Checking the main/img/icons/XXX/ folder
762
                $icon = $w_code_path.'img/icons/'.$size_extra.$image;
763
            }
764 View Code Duplication
        } else {
765
            if (is_file($code_path.'img/icons/'.$size_extra.$image)) {
766
                // Checking the main/img/icons/XXX/ folder
767
                $icon = $w_code_path.'img/icons/'.$size_extra.$image;
768
            }
769
        }
770
771
        // Special code to enable SVG - refs #7359 - Needs more work
772
        // The code below does something else to "test out" SVG: for each icon,
773
        // it checks if there is an SVG version. If so, it uses it.
774
        // When moving this to production, the return_icon() calls should
775
        // ask for the SVG version directly
776
        $testServer = api_get_setting('server_type');
777
        if ($testServer == 'test' && $return_only_path == false) {
778
            $svgImage = substr($image, 0, -3) . 'svg';
779
            if (is_file($code_path . $theme . 'svg/' . $svgImage)) {
780
                $icon = $w_code_path . $theme . 'svg/' . $svgImage;
781
            } elseif (is_file($code_path . 'img/icons/svg/' . $svgImage)) {
782
                $icon = $w_code_path . 'img/icons/svg/' . $svgImage;
783
            }
784
785
            if (empty($additional_attributes['height'])) {
786
                $additional_attributes['height'] = $size;
787
            }
788
            if (empty($additional_attributes['width'])) {
789
                $additional_attributes['width'] = $size;
790
            }
791
        }
792
793
        $icon = api_get_cdn_path($icon);
794
795
        if ($return_only_path) {
796
            return $icon;
797
798
        }
799
800
        $img = self::img($icon, $alt_text, $additional_attributes);
801
        if (SHOW_TEXT_NEAR_ICONS == true && !empty($alt_text)) {
802
            if ($show_text) {
803
                $img = "$img $alt_text";
804
            }
805
        }
806
807
        return $img;
808
    }
809
810
    /**
811
     * Returns the htmlcode for an image
812
     *
813
     * @param string $image_path the filename of the file (in the main/img/ folder
814
     * @param string $alt_text the alt text (probably a language variable)
815
     * @param array  $additional_attributes (for instance height, width, onclick, ...)
816
     * @param boolean $filterPath Optional. Whether filter the image path. Default is true
817
     * @author Julio Montoya 2010
818
     */
819
    public static function img($image_path, $alt_text = '', $additional_attributes = array(), $filterPath = true)
820
    {
821
        // Sanitizing the parameter $image_path
822
        if ($filterPath) {
823
            $image_path = Security::filter_img_path($image_path);
824
        }
825
826
        // alt text = the image name if there is none provided (for XHTML compliance)
827
        if ($alt_text == '') {
828
            $alt_text = basename($image_path);
829
        }
830
831
        $additional_attributes['src'] = $image_path;
832
833
        if (empty($additional_attributes['alt'])) {
834
            $additional_attributes['alt'] = $alt_text;
835
        }
836
        if (empty($additional_attributes['title'])) {
837
            $additional_attributes['title'] = $alt_text;
838
        }
839
840
        return self::tag('img', '', $additional_attributes);
841
    }
842
843
    /**
844
     * Returns the htmlcode for a tag (h3, h1, div, a, button), etc
845
     *
846
     * @param string $tag the tag name
847
     * @param string $content the tag's content
848
     * @param array $additional_attributes (for instance height, width, onclick, ...)
849
     * @author Julio Montoya 2010
850
     */
851
    public static function tag($tag, $content, $additional_attributes = array())
852
    {
853
        $attribute_list = '';
854
        // Managing the additional attributes
855
        if (!empty($additional_attributes) && is_array($additional_attributes)) {
856
            $attribute_list = '';
857
            foreach ($additional_attributes as $key => & $value) {
858
                $attribute_list .= $key.'="'.$value.'" ';
859
            }
860
        }
861
        //some tags don't have this </XXX>
862
        if (in_array($tag, array('img','input','br'))) {
863
            $return_value = '<'.$tag.' '.$attribute_list.' />';
864
        } else {
865
            $return_value = '<'.$tag.' '.$attribute_list.' > '.$content.'</'.$tag.'>';
866
        }
867
        return $return_value;
868
    }
869
870
    /**
871
     * Creates a URL anchor
872
     * @param string $name
873
     * @param string $url
874
     * @param array $attributes
875
     *
876
     * @return string
877
     */
878
    public static function url($name, $url, $attributes = array())
879
    {
880
        if (!empty($url)) {
881
            $url = preg_replace('#&amp;#', '&', $url);
882
            $url = htmlspecialchars($url, ENT_QUOTES, 'UTF-8');
883
            $attributes['href'] = $url;
884
        }
885
        return self::tag('a', $name, $attributes);
886
    }
887
888
    /**
889
     * Creates a div tag
890
     *
891
     * @param string $content
892
     * @param array $attributes
893
     * @return string
894
     */
895
    public static function div($content, $attributes = array())
896
    {
897
        return self::tag('div', $content, $attributes);
898
    }
899
900
    /**
901
     * Creates a span tag
902
     */
903
    public static function span($content, $attributes = array())
904
    {
905
        return self::tag('span', $content, $attributes);
906
    }
907
908
    /**
909
     * Displays an HTML input tag
910
     *
911
     */
912
    public static function input($type, $name, $value, $attributes = array())
913
    {
914
         if (isset($type)) {
915
             $attributes['type']= $type;
916
         }
917
         if (isset($name)) {
918
             $attributes['name']= $name;
919
         }
920
         if (isset($value)) {
921
             $attributes['value']= $value;
922
        }
923
        return self::tag('input', '', $attributes);
924
    }
925
926
    /**
927
     * @param $name
928
     * @param $value
929
     * @param array $attributes
930
     * @return string
931
     */
932
    public static function button($name, $value, $attributes = array())
933
    {
934
    	if (!empty($name)) {
935
            $attributes['name'] = $name;
936
    	}
937
    	return self::tag('button', $value, $attributes);
938
    }
939
940
    /**
941
     * Displays an HTML select tag
942
     *
943
     */
944
    public static function select(
945
        $name,
946
        $values,
947
        $default = -1,
948
        $extra_attributes = array(),
949
        $show_blank_item = true,
950
        $blank_item_text = null
951
    ) {
952
        $html = '';
953
        $extra = '';
954
        $default_id = 'id="' . $name . '" ';
955
        foreach ($extra_attributes as $key => $parameter) {
956
            if ($key == 'id') {
957
                $default_id = '';
958
            }
959
            $extra .= $key . '="' . $parameter . '" ';
960
        }
961
        $html .= '<select name="' . $name . '" ' . $default_id . ' ' . $extra . '>';
962
963
        if ($show_blank_item) {
964
            if (empty($blank_item_text)) {
965
                $blank_item_text = get_lang('Select');
966
            } else {
967
                $blank_item_text = Security::remove_XSS($blank_item_text);
968
            }
969
            $html .= self::tag('option', '-- ' . $blank_item_text . ' --', array('value' => '-1'));
970
        }
971
        if ($values) {
972
            foreach ($values as $key => $value) {
973
                if (is_array($value) && isset($value['name'])) {
974
                    $value = $value['name'];
975
                }
976
                $html .= '<option value="' . $key . '"';
977
978
                if (is_array($default)) {
979
                    foreach ($default as $item) {
980
                        if ($item == $key) {
981
                            $html .= ' selected="selected"';
982
                            break;
983
                        }
984
                    }
985
                } else {
986
                    if ($default == $key) {
987
                        $html .= ' selected="selected"';
988
                    }
989
                }
990
991
                $html .= '>' . $value . '</option>';
992
            }
993
        }
994
        $html .= '</select>';
995
        return $html;
996
    }
997
998
    /**
999
     * Creates a tab menu
1000
     * Requirements: declare the jquery, jquery-ui libraries + the jquery-ui.css
1001
     * in the $htmlHeadXtra variable before the display_header
1002
     * Add this script
1003
     * @example
1004
             * <script>
1005
                    $(function() {
1006
                        $( "#tabs" ).tabs();
1007
                    });
1008
                </script>
1009
     * @param   array   list of the tab titles
1010
     * @param   array   content that will be showed
1011
     * @param   string  the id of the container of the tab in the example "tabs"
1012
     * @param   array   attributes for the ul
1013
     *
1014
     */
1015
    public static function tabs($header_list, $content_list, $id = 'tabs', $attributes = array(), $ul_attributes = array())
1016
    {
1017
        if (empty($header_list) || count($header_list) == 0 ) {
1018
            return '';
1019
        }
1020
1021
        $lis = '';
1022
        $i = 1;
1023
        foreach ($header_list as $item) {
1024
            $active = '';
1025
            if ($i == 1) {
1026
                $active = ' active';
1027
            }
1028
            $item = self::tag('a', $item, array('href'=>'#'.$id.'-'.$i, 'role'=> 'tab'));
1029
            $ul_attributes['data-toggle'] = 'tab';
1030
            $ul_attributes['role'] = 'presentation';
1031
            $ul_attributes['class'] = $active;
1032
            $lis .= self::tag('li', $item, $ul_attributes);
1033
            $i++;
1034
        }
1035
        $ul = self::tag('ul', $lis, ['class' => 'nav nav-tabs', 'role'=> 'tablist']);
1036
1037
        $i = 1;
1038
        $divs = '';
1039
        foreach ($content_list as $content) {
1040
            $active = '';
1041
            if ($i == 1) {
1042
                $active = ' active';
1043
            }
1044
            $divs .= self::tag('div', $content, array('id'=> $id.'-'.$i, 'class' => 'tab-pane '.$active, 'role' => 'tabpanel'));
1045
            $i++;
1046
        }
1047
1048
        $attributes['id'] = $id;
1049
        $attributes['role'] = 'tabpanel';
1050
        $attributes['class'] = 'tab-wrapper';
1051
1052
        $main_div = self::tag('div', $ul.self::tag('div', $divs, ['class' => 'tab-content']), $attributes);
1053
1054
        return $main_div ;
1055
    }
1056
1057
    /**
1058
     * @param $headers
1059
     * @param null $selected
1060
     *
1061
     * @return string
1062
     */
1063
    public static function tabsOnlyLink($headers, $selected = null)
1064
    {
1065
         $id = uniqid();
1066
         $i = 1;
1067
         $lis = null;
1068
         foreach ($headers as $item) {
1069
            $class = null;
1070
            if ($i == $selected) {
1071
                $class = 'active';
1072
            }
1073
             $item = self::tag(
1074
                 'a',
1075
                 $item['content'],
1076
                 array('id' => $id.'-'.$i, 'href' => $item['url'])
1077
             );
1078
             $lis .= self::tag('li', $item, array('class' => $class));
1079
            $i++;
1080
        }
1081
        return self::tag('ul', $lis, array('class' => 'nav nav-tabs tabs-margin'));
1082
    }
1083
1084
    /**
1085
     * In order to display a grid using jqgrid you have to:
1086
     * @example
1087
     * After your Display::display_header function you have to add the nex javascript code:     *
1088
     * <script>
1089
     *   echo Display::grid_js('my_grid_name', $url,$columns, $column_model, $extra_params,array());
1090
     *   // for more information of this function check the grid_js() function
1091
     * </script>
1092
     * //Then you have to call the grid_html
1093
     * echo Display::grid_html('my_grid_name');
1094
     * As you can see both function use the same "my_grid_name" this is very important otherwise nothing will work
1095
     *
1096
     * @param   string  the div id, this value must be the same with the first parameter of Display::grid_js()
1097
     * @return  string  html
1098
     *
1099
     */
1100
    public static function grid_html($div_id)
1101
    {
1102
        $table  = self::tag('table','', array('id' => $div_id));
1103
        $table .= self::tag('div','', array('id' => $div_id.'_pager'));
1104
        return $table;
1105
    }
1106
1107
    /**
1108
     * @param string $label
1109
     * @param string $form_item
1110
     * @return string
1111
     */
1112
    public static function form_row($label, $form_item)
1113
    {
1114
        $label = self::span($label, array('class' =>'control-label'));
1115
        $form_item = self::div($form_item, array('class' =>'controls'));
1116
        return self::div($label.$form_item, array('class'=>'control-group'));
1117
    }
1118
1119
    /**
1120
     * This is a wrapper to use the jqgrid in Chamilo.
1121
     * For the other jqgrid options visit http://www.trirand.com/jqgridwiki/doku.php?id=wiki:options
1122
     * This function need to be in the ready jquery function
1123
     * example --> $(function() { <?php echo Display::grid_js('grid' ...); ?> }
1124
     * In order to work this function needs the Display::grid_html function with the same div id
1125
     *
1126
     * @param   string  $div_id div id
1127
     * @param   string  $url url where the jqgrid will ask for data (if datatype = json)
1128
     * @param   array   $column_names Visible columns (you should use get_lang). An array in which we place the names of the columns.
1129
     * 					This is the text that appears in the head of the grid (Header layer).
1130
     * 					Example: colname   {name:'date',     index:'date',   width:120, align:'right'},
1131
     * @param   array   $column_model the column model :  Array which describes the parameters of the columns.This is the most important part of the grid.
1132
     * 					For a full description of all valid values see colModel API. See the url above.
1133
     * @param   array   $extra_params extra parameters
1134
     * @param   array   $data data that will be loaded
1135
     * @param	string	$formatter A string that will be appended to the JSON returned
1136
     * @param	bool	$fixed_width not implemented yet
1137
     * @return  string  the js code
1138
     *
1139
     */
1140
    public static function grid_js(
1141
        $div_id,
1142
        $url,
1143
        $column_names,
1144
        $column_model,
1145
        $extra_params,
1146
        $data = array(),
1147
        $formatter = '',
1148
        $fixed_width = false
1149
    ) {
1150
        $obj = new stdClass();
1151
        $obj->first = 'first';
1152
1153
        if (!empty($url)) {
1154
            $obj->url = $url;
1155
        }
1156
1157
        //This line should only be used/modified in case of having characters
1158
        // encoding problems - see #6159
1159
        //$column_names = array_map("utf8_encode", $column_names);
1160
1161
        $obj->colNames      = $column_names;
1162
        $obj->colModel      = $column_model;
1163
        $obj->pager         = '#'.$div_id.'_pager';
1164
        $obj->datatype  = 'json';
1165
        $obj->viewrecords = 'true';
1166
1167
        $all_value = 10000000;
1168
1169
        // Default row quantity
1170
        if (!isset($extra_params['rowList'])) {
1171
            $extra_params['rowList'] = array(20, 50, 100, 500, 1000, $all_value);
1172
        }
1173
1174
        $json = '';
1175
        if (!empty($extra_params['datatype'])) {
1176
            $obj->datatype = $extra_params['datatype'];
1177
        }
1178
1179
        // Row even odd style.
1180
        $obj->altRows = true;
1181
        if (!empty($extra_params['altRows'])) {
1182
            $obj->altRows = $extra_params['altRows'];
1183
        }
1184
1185
        if (!empty($extra_params['sortname'])) {
1186
            $obj->sortname = $extra_params['sortname'];
1187
        }
1188
1189
        if (!empty($extra_params['sortorder'])) {
1190
            $obj->sortorder = $extra_params['sortorder'];
1191
        }
1192
1193
        if (!empty($extra_params['rowList'])) {
1194
            $obj->rowList = $extra_params['rowList'];
1195
        }
1196
        //Sets how many records we want to view in the grid
1197
        $obj->rowNum = 20;
1198
        if (!empty($extra_params['rowNum'])) {
1199
            $obj->rowNum = $extra_params['rowNum'];
1200
        }
1201
1202
        if (!empty($extra_params['viewrecords'])) {
1203
            $obj->viewrecords = $extra_params['viewrecords'];
1204
        }
1205
1206
        $beforeSelectRow = null;
1207
        if (isset($extra_params['beforeSelectRow'])) {
1208
            $beforeSelectRow = "beforeSelectRow: ".$extra_params['beforeSelectRow'].", ";
1209
            unset($extra_params['beforeSelectRow']);
1210
        }
1211
1212
        // Adding extra params
1213
        if (!empty($extra_params)) {
1214
            foreach ($extra_params as $key => $element) {
1215
                // the groupHeaders key gets a special treatment
1216
                if ($key != 'groupHeaders') {
1217
                    $obj->$key = $element;
1218
                }
1219
            }
1220
        }
1221
1222
        // Adding static data.
1223
        if (!empty($data)) {
1224
            $data_var = $div_id.'_data';
1225
            $json.=' var '.$data_var.' = '.json_encode($data).';';
1226
            $obj->data = $data_var;
1227
            $obj->datatype = 'local';
1228
            $json.="\n";
1229
        }
1230
1231
        $obj->end = 'end';
1232
1233
        $json_encode = json_encode($obj);
1234
1235
        if (!empty($data)) {
1236
            //Converts the "data":"js_variable" to "data":js_variable,
1237
            // otherwise it will not work
1238
            $json_encode = str_replace('"data":"'.$data_var.'"', '"data":'.$data_var.'', $json_encode);
1239
        }
1240
1241
        // Fixing true/false js values that doesn't need the ""
1242
        $json_encode = str_replace(':"true"',':true',$json_encode);
1243
        // wrap_cell is not a valid jqgrid attributes is a hack to wrap a text
1244
        $json_encode = str_replace('"wrap_cell":true', 'cellattr : function(rowId, value, rowObject, colModel, arrData) { return \'class = "jqgrid_whitespace"\'; }', $json_encode);
1245
        $json_encode = str_replace(':"false"',':false',$json_encode);
1246
        $json_encode = str_replace('"formatter":"action_formatter"', 'formatter:action_formatter', $json_encode);
1247
        $json_encode = str_replace(array('{"first":"first",','"end":"end"}'), '', $json_encode);
1248
1249
        // Creating the jqgrid element.
1250
        $json .= '$("#'.$div_id.'").jqGrid({';
1251
        //$json .= $beforeSelectRow;
1252
1253
        $json .= $json_encode;
1254
1255
        $json .= '});';
1256
1257
        // Grouping headers option
1258
        if (isset($extra_params['groupHeaders'])) {
1259
            $groups = '';
1260
            foreach ($extra_params['groupHeaders'] as $group) {
1261
                //{ "startColumnName" : "courses", "numberOfColumns" : 1, "titleText" : "Order Info" },
1262
                $groups .= '{ "startColumnName" : "' . $group['startColumnName'] . '", "numberOfColumns" : ' . $group['numberOfColumns'] . ', "titleText" : "' . $group['titleText']  . '" },';
1263
1264
            }
1265
            $json .= '$("#'.$div_id.'").jqGrid("setGroupHeaders", {
1266
                "useColSpanStyle" : false,
1267
                "groupHeaders"    : [
1268
                    ' . $groups . '
1269
                ]
1270
            });';
1271
        }
1272
1273
        $all_text = addslashes(get_lang('All'));
1274
        $json .= '$("'.$obj->pager.' option[value='.$all_value.']").text("'.$all_text.'");';
1275
        $json.= "\n";
1276
        // Adding edit/delete icons.
1277
        $json.= $formatter;
1278
1279
        return $json;
1280
    }
1281
1282
    /**
1283
     * @param array $headers
1284
     * @param array $rows
1285
     * @param array $attributes
1286
     * @return string
1287
     */
1288
    public static function table($headers, $rows, $attributes = array())
1289
    {
1290
    	if (empty($attributes)) {
1291
    		$attributes['class'] = 'data_table';
1292
        }
1293
        $table = new HTML_Table($attributes);
1294
        $row = 0;
1295
        $column = 0;
1296
1297
        // Course headers
1298
        if (!empty($headers)) {
1299
	        foreach ($headers as $item) {
1300
	            $table->setHeaderContents($row, $column, $item);
1301
	            $column++;
1302
	        }
1303
	        $row = 1;
1304
	        $column = 0;
1305
        }
1306
1307
        if (!empty($rows)) {
1308
	        foreach($rows as $content) {
1309
	            $table->setCellContents($row, $column, $content);
1310
                $row++;
1311
            }
1312
        }
1313
        return $table->toHtml();
1314
    }
1315
1316
    /**
1317
     * Returns the "what's new" icon notifications
1318
     *
1319
     * The general logic of this function is to track the last time the user
1320
     * entered the course and compare to what has changed inside this course
1321
     * since then, based on the item_property table inside this course. Note that,
1322
     * if the user never entered the course before, he will not see notification
1323
     * icons. This function takes session ID into account (if any) and only shows
1324
     * the corresponding notifications.
1325
     * @param array     Course information array, containing at least elements 'db' and 'k'
1326
     * @return string   The HTML link to be shown next to the course
1327
     */
1328
    public static function show_notification($course_info)
1329
    {
1330
        if (empty($course_info)) {
1331
            return '';
1332
        }
1333
1334
        $t_track_e_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS);
1335
        $course_tool_table = Database::get_course_table(TABLE_TOOL_LIST);
1336
        $tool_edit_table = Database::get_course_table(TABLE_ITEM_PROPERTY);
1337
        $course_code = Database::escape_string($course_info['code']);
1338
1339
        $user_id = api_get_user_id();
1340
        $course_id = intval($course_info['real_id']);
1341
        $sessionId = intval($course_info['id_session']);
1342
1343
        // Get the user's last access dates to all tools of this course
1344
        $sql = "SELECT *
1345
                FROM $t_track_e_access
1346
                WHERE
1347
                    c_id = $course_id AND
1348
                    access_user_id = '$user_id' AND
1349
                    access_session_id ='".$sessionId."'";
1350
        $resLastTrackInCourse = Database::query($sql);
1351
1352
        $oldestTrackDate = $oldestTrackDateOrig = '3000-01-01 00:00:00';
1353
        while ($lastTrackInCourse = Database::fetch_array($resLastTrackInCourse)) {
1354
            $lastTrackInCourseDate[$lastTrackInCourse['access_tool']] = $lastTrackInCourse['access_date'];
1355
            if ($oldestTrackDate > $lastTrackInCourse['access_date']) {
1356
                $oldestTrackDate = $lastTrackInCourse['access_date'];
1357
            }
1358
        }
1359
1360
        if ($oldestTrackDate == $oldestTrackDateOrig) {
1361
            //if there was no connexion to the course ever, then take the
1362
            // course creation date as a reference
1363
            $oldestTrackDate = $course_info['creation_date'];
1364
        }
1365
1366
        $sessionCondition = api_get_session_condition(
1367
            $sessionId,
1368
            true,
1369
            false,
1370
            'tet.session_id'
1371
        );
1372
1373
        // Get the last edits of all tools of this course.
1374
        $sql = "SELECT
1375
                    tet.*,
1376
                    tet.lastedit_date last_date,
1377
                    tet.tool tool,
1378
                    tet.ref ref,
1379
                    tet.lastedit_type type,
1380
                    tet.to_group_id group_id,
1381
                    ctt.image image,
1382
                    ctt.link link
1383
                FROM $tool_edit_table tet
1384
                INNER JOIN $course_tool_table ctt
1385
                ON tet.c_id = ctt.c_id
1386
                WHERE
1387
                    tet.c_id = $course_id AND
1388
                    tet.lastedit_date > '$oldestTrackDate' ".
1389
                    // Special hack for work tool, which is called student_publication in c_tool and work in c_item_property :-/ BT#7104
1390
                    " AND (ctt.name = tet.tool OR (ctt.name = 'student_publication' AND tet.tool = 'work'))
1391
                    AND ctt.visibility = '1'
1392
                    AND tet.lastedit_user_id != $user_id $sessionCondition
1393
                 ORDER BY tet.lastedit_date";
1394
1395
        $res = Database::query($sql);
1396
        // Get the group_id's with user membership.
1397
        $group_ids = GroupManager :: get_group_ids($course_info['real_id'], $user_id);
1398
        $group_ids[] = 0; //add group 'everyone'
1399
        $notifications = array();
1400
        // Filter all last edits of all tools of the course
1401
        while ($res && ($item_property = Database::fetch_array($res, 'ASSOC'))) {
1402
1403
            // First thing to check is if the user never entered the tool
1404
            // or if his last visit was earlier than the last modification.
1405
            if ((!isset($lastTrackInCourseDate[$item_property['tool']])
1406
                 || $lastTrackInCourseDate[$item_property['tool']] < $item_property['lastedit_date'])
1407
                // Drop the tool elements that are part of a group that the
1408
                // user is not part of.
1409
                && ((in_array($item_property['to_group_id'], $group_ids)
1410
                // Drop the dropbox, notebook and chat tools (we don't care)
1411
                && (
1412
                        //$item_property['tool'] != TOOL_DROPBOX &&
1413
                        $item_property['tool'] != TOOL_NOTEBOOK &&
1414
                        $item_property['tool'] != TOOL_CHAT)
1415
                   )
1416
                )
1417
                // Take only what's visible or "invisible but where the user is a teacher" or where the visibility is unset.
1418
                && ($item_property['visibility'] == '1'
1419
                    || ($course_info['status'] == '1' && $item_property['visibility'] == '0')
1420
                    || !isset($item_property['visibility']))
1421
            ) {
1422
                // Also drop announcements and events that are not for the user or his group.
1423
                if ((
1424
                        $item_property['tool'] == TOOL_ANNOUNCEMENT ||
1425
                        $item_property['tool'] == TOOL_CALENDAR_EVENT
1426
                    ) &&
1427
                    (
1428
                        ($item_property['to_user_id'] != $user_id) &&
1429
                        (!isset($item_property['to_group_id']) || !in_array($item_property['to_group_id'], $group_ids)))
1430
                ) {
1431
                   continue;
1432
                }
1433
1434
                // If it's a survey, make sure the user's invited. Otherwise drop it.
1435
                if ($item_property['tool'] == TOOL_SURVEY) {
1436
                    $survey_info = SurveyManager::get_survey($item_property['ref'], 0, $course_code);
1437
                    if (!empty($survey_info)) {
1438
                        $invited_users = SurveyUtil::get_invited_users(
1439
                            $survey_info['code'],
1440
                            $course_code
1441
                        );
1442
                        if (!in_array($user_id, $invited_users['course_users'])) {
1443
                            continue;
1444
                        }
1445
                    }
1446
                }
1447
1448
                // If it's a learning path, ensure it is currently visible to the user
1449
                if ($item_property['tool'] == TOOL_LEARNPATH) {
1450
                    if (!learnpath::is_lp_visible_for_student($item_property['ref'], $user_id, $course_code)) {
1451
                        continue;
1452
                    }
1453
                }
1454
1455
                if ($item_property['tool'] == TOOL_DROPBOX) {
1456
                    $item_property['link'] = 'dropbox/dropbox_download.php?id='.$item_property['ref'];
1457
                }
1458
1459
                if ($item_property['tool'] == 'work' &&
1460
                    $item_property['type'] == 'DirectoryCreated'
1461
                ) {
1462
                    $item_property['lastedit_type'] = 'WorkAdded';
1463
                }
1464
                $notifications[$item_property['tool']] = $item_property;
1465
            }
1466
        }
1467
1468
        // Show all tool icons where there is something new.
1469
        $return = '&nbsp;';
1470
        foreach($notifications as $notification) {
1471
            $lastDate = date('d/m/Y H:i', convert_sql_date($notification['lastedit_date']));
1472
            $type = $notification['lastedit_type'];
1473
            $label = get_lang('TitleNotification').": ".get_lang($type)." ($lastDate)";
1474
1475
            if (strpos($notification['link'], '?') === false) {
1476
                $notification['link'] = $notification['link'].'?notification=1';
1477
            } else {
1478
                $notification['link'] = $notification['link'].'&notification=1';
1479
            }
1480
            $return .= Display::url(
1481
                Display::return_icon($notification['image'], $label),
1482
                api_get_path(WEB_CODE_PATH).
1483
                $notification['link'].'&cidReq='.$course_code.
1484
                '&ref='.$notification['ref'].
1485
                '&gidReq='.$notification['to_group_id'].
1486
                '&id_session='.$sessionId
1487
            ).'&nbsp;';
1488
        }
1489
1490
        return $return;
1491
    }
1492
1493
    /**
1494
     * Get the session box details as an array
1495
     * @param int       Session ID
1496
     * @return array    Empty array or session array
1497
     * ['title'=>'...','category'=>'','dates'=>'...','coach'=>'...','active'=>true/false,'session_category_id'=>int]
1498
     */
1499
    public static function get_session_title_box($session_id)
1500
    {
1501
        global $nosession;
1502
1503
        if (!$nosession) {
1504
            global $now, $date_start, $date_end;
1505
        }
1506
1507
        $output = array();
1508
        if (!$nosession) {
1509
            $main_user_table        = Database :: get_main_table(TABLE_MAIN_USER);
1510
            $tbl_session            = Database :: get_main_table(TABLE_MAIN_SESSION);
1511
            $active = false;
1512
            // Request for the name of the general coach
1513
            $sql ='SELECT tu.lastname, tu.firstname, ts.*
1514
                    FROM '.$tbl_session.' ts
1515
                    LEFT JOIN '.$main_user_table .' tu
1516
                    ON ts.id_coach = tu.user_id
1517
                    WHERE ts.id = '.intval($session_id);
1518
            $rs = Database::query($sql);
1519
            $session_info = Database::store_result($rs, 'ASSOC');
1520
            $session_info = $session_info[0];
1521
1522
            $session = array();
1523
            $session['title'] = $session_info['name'];
1524
            $session['coach'] = '';
1525
            $session['dates'] =  '';
1526
1527
            if (
1528
                (
1529
                    $session_info['access_end_date'] == '0000-00-00' &&
1530
                    $session_info['access_start_date'] == '0000-00-00'
1531
                ) ||
1532
                (
1533
                    empty($session_info['access_end_date']) && empty($session_info['access_start_date'])
1534
                )
1535
            ) {
1536 View Code Duplication
                if (api_get_setting('show_session_coach') === 'true') {
1537
                    $session['coach'] = get_lang('GeneralCoach').': '.api_get_person_name($session_info['firstname'], $session_info['lastname']);
1538
                }
1539
                if (isset($session_info['duration']) && !empty($session_info['duration'])) {
1540
                    $userDurationData = SessionManager::getUserSession(
1541
                            api_get_user_id(),
1542
                            $session_id
1543
                    );
1544
                    $userDuration = 0;
1545
                    if (isset($userDurationData['duration'])) {
1546
                        $userDuration = intval($userDurationData['duration']);
1547
                    }
1548
                    $totalDuration = $session_info['duration'] + $userDuration;
1549
1550
                    $daysLeft = SessionManager::getDayLeftInSession(
1551
                        $session_id,
1552
                        api_get_user_id(),
1553
                        $totalDuration
1554
                    );
1555
                    $session['duration'] = sprintf(get_lang('SessionDurationXDaysLeft'), $daysLeft);
1556
                }
1557
                $active = true;
1558
            } else {
1559
                $start = $stop = false;
1560
                $start_buffer = $stop_buffer = '';
1561 View Code Duplication
                if ($session_info['access_start_date'] == '0000-00-00' || empty($session_info['access_start_date'])) {
1562
                    $session_info['access_start_date'] = '';
1563
                } else {
1564
                    $start = true;
1565
                    $start_buffer = $session_info['access_start_date'];
1566
                    $session_info['access_start_date'] = $session_info['access_start_date'];
1567
                }
1568 View Code Duplication
                if ($session_info['access_end_date'] == '0000-00-00' || empty($session_info['access_end_date'])) {
1569
                    $session_info['access_end_date'] = '';
1570
                } else {
1571
                    $stop = true;
1572
                    $stop_buffer = $session_info['access_end_date'];
1573
                    $session_info['access_end_date'] = $session_info['access_end_date'];
1574
                }
1575
                if ($start && $stop) {
1576
                    $session['dates'] = Display::tag(
1577
                        'em',
1578
                        sprintf(
1579
                            get_lang('FromDateXToDateY'),
1580
                            api_format_date($start_buffer),
1581
                            api_format_date($stop_buffer)
1582
                        )
1583
                    );
1584
                } else {
1585
                    $start_buffer = $stop_buffer = null;
1586
1587
                    if (!empty($session_info['access_start_date'])) {
1588
                        $start_buffer = sprintf(
1589
                            get_lang('FromDateX'),
1590
                            api_format_date($session_info['access_start_date'])
1591
                        );
1592
                    }
1593
1594
                    if (!empty($session_info['access_end_date'])) {
1595
                        $stop_buffer = sprintf(
1596
                            get_lang('UntilDateX'),
1597
                            api_format_date($session_info['access_end_date'])
1598
                        );
1599
                    }
1600
1601
                    $session['dates'] = Display::tag(
1602
                        'em',
1603
                        "$start_buffer $stop_buffer"
1604
                    );
1605
                }
1606
1607 View Code Duplication
                if ( api_get_setting('show_session_coach') === 'true' ) {
1608
                    $session['coach'] = get_lang('GeneralCoach') . ': ' . api_get_person_name(
1609
                        $session_info['firstname'],
1610
                        $session_info['lastname']
1611
                    );
1612
                }
1613
                $active = ($date_start <= $now && $date_end >= $now);
1614
            }
1615
            $session['active'] = $active;
1616
            $session['session_category_id'] = $session_info['session_category_id'];
1617
1618
            $session['description'] = $session_info['description'];
1619
            $session['show_description'] = $session_info['show_description'];
1620
1621
            $entityManager = Database::getManager();
1622
            $fieldValuesRepo = $entityManager->getRepository('ChamiloCoreBundle:ExtraFieldValues');
1623
            $extraFieldValues = $fieldValuesRepo->getVisibleValues(
1624
                Chamilo\CoreBundle\Entity\ExtraField::SESSION_FIELD_TYPE,
1625
                $session_id
1626
            );
1627
1628
            $session['extra_fields'] = [];
1629
1630
            foreach ($extraFieldValues as $value) {
1631
                $session['extra_fields'][] = [
1632
                    'field' => [
1633
                        'variable' => $value->getField()->getVariable(),
1634
                        'display_text' => $value->getField()->getDisplayText()
1635
                    ],
1636
                    'value' => $value->getValue()
1637
                ];
1638
            }
1639
1640
            $output = $session;
1641
        }
1642
        return $output;
1643
    }
1644
1645
    /**
1646
     * Return the five star HTML
1647
     *
1648
     * @param  string  id of the rating ul element
1649
     * @param  string  url that will be added (for jquery see hot_courses.tpl)
1650
	 * @param	string	point info array see function CourseManager::get_course_ranking()
1651
	 * @param	bool	add a div wrapper
1652
	 * @todo	use     templates
1653
     **/
1654
    public static function return_rating_system($id, $url, $point_info = array(), $add_div_wrapper = true)
1655
    {
1656
		$number_of_users_who_voted = isset($point_info['users_who_voted']) ? $point_info['users_who_voted'] : null;
1657
		$percentage = isset($point_info['point_average']) ? $point_info['point_average'] : 0;
1658
1659
		if (!empty($percentage)) {
1660
            $percentage = $percentage*125/100;
1661
        }
1662
		$accesses =  isset($point_info['accesses']) ? $point_info['accesses'] : 0;
1663
1664
		$star_label = sprintf(get_lang('XStarsOutOf5'), $point_info['point_average_star']);
1665
1666
        $html = '<ul id="'.$id.'" class="star-rating">
1667
					<li class="current-rating" style="width:'.$percentage.'px;"></li>
1668
					<li><a href="javascript:void(0);" data-link="'.$url.'&amp;star=1" title="'.$star_label.'" class="one-star">1</a></li>
1669
					<li><a href="javascript:void(0);" data-link="'.$url.'&amp;star=2" title="'.$star_label.'" class="two-stars">2</a></li>
1670
					<li><a href="javascript:void(0);" data-link="'.$url.'&amp;star=3" title="'.$star_label.'" class="three-stars">3</a></li>
1671
					<li><a href="javascript:void(0);" data-link="'.$url.'&amp;star=4" title="'.$star_label.'" class="four-stars">4</a></li>
1672
					<li><a href="javascript:void(0);" data-link="'.$url.'&amp;star=5" title="'.$star_label.'" class="five-stars">5</a></li>
1673
				</ul>';
1674
1675
		$labels = array();
1676
1677
		$labels[]= $number_of_users_who_voted == 1 ? $number_of_users_who_voted.' '.get_lang('Vote') : $number_of_users_who_voted.' '.get_lang('Votes');
1678
		$labels[]= $accesses == 1 ? $accesses.' '.get_lang('Visit') : $accesses.' '.get_lang('Visits');
1679
		if (!empty($number_of_users_who_voted)) {
1680
			$labels[]= get_lang('Average').' '.$point_info['point_average_star'].'/5';
1681
		}
1682
1683
		$labels[]= $point_info['user_vote']  ? get_lang('YourVote').' ['.$point_info['user_vote'].']' : get_lang('YourVote'). ' [?] ';
1684
1685
		if (!$add_div_wrapper && api_is_anonymous()) {
1686
			$labels[]= Display::tag('span', get_lang('LoginToVote'), array('class' => 'error'));
1687
		}
1688
1689
        $html .= Display::div(implode(' | ', $labels) , array('id' =>  'vote_label_'.$id, 'class' => 'vote_label_info'));
1690
        $html .= ' '.Display::span(' ', array('id' =>  'vote_label2_'.$id));
1691
1692
        if ($add_div_wrapper) {
1693
			$html = Display::div($html, array('id' => 'rating_wrapper_'.$id));
1694
		}
1695
1696
        return $html;
1697
    }
1698
1699
    public static function return_default_table_class()
1700
    {
1701
        return 'table table-bordered';
1702
    }
1703
1704
    /**
1705
     * @param string $title
1706
     * @param string $second_title
1707
     * @param string $size
1708
     * @param bool $filter
1709
     * @return string
1710
     */
1711
    public static function page_header($title, $second_title = null, $size = 'h2', $filter = true)
1712
    {
1713
        if ($filter) {
1714
            $title = Security::remove_XSS($title);
1715
        }
1716
1717
        if (!empty($second_title)) {
1718
            if ($filter) {
1719
                $second_title = Security::remove_XSS($second_title);
1720
            }
1721
            $title .= "<small> $second_title<small>";
1722
        }
1723
        return '<div class="page-header"><'.$size.'>'.$title.'</'.$size.'></div>';
1724
    }
1725
1726
    public static function page_header_and_translate($title, $second_title = null)
1727
    {
1728
        $title = get_lang($title);
1729
        return self::page_header($title, $second_title);
1730
    }
1731
1732
     public static function page_subheader_and_translate($title, $second_title = null)
1733
     {
1734
        $title = get_lang($title);
1735
        return self::page_subheader($title, $second_title);
1736
    }
1737
1738
    public static function page_subheader($title, $second_title = null, $size = 'h3')
1739
    {
1740
        if (!empty($second_title)) {
1741
            $second_title = Security::remove_XSS($second_title);
1742
            $title .= "<small> $second_title<small>";
1743
        }
1744
        return '<'.$size.'>'.Security::remove_XSS($title).'</'.$size.'>';
1745
    }
1746
1747
    public static function page_subheader2($title, $second_title = null)
1748
    {
1749
        return self::page_header($title, $second_title, 'h4');
1750
    }
1751
1752
    public static function page_subheader3($title, $second_title = null)
1753
    {
1754
        return self::page_header($title, $second_title, 'h5');
1755
    }
1756
1757
    /**
1758
     * @param array $list
1759
     * @return null|string
1760
     */
1761
    public static function description($list)
1762
    {
1763
        $html = null;
1764
        if (!empty($list)) {
1765
            $html = '<dl class="dl-horizontal">';
1766
            foreach ($list as $item) {
1767
                $html .= '<dt>' . $item['title'] . '</dt>';
1768
                $html .= '<dd>' . $item['content'] . '</dd>';
1769
            }
1770
            $html .= '</dl>';
1771
        }
1772
        return $html;
1773
    }
1774
1775
    /**
1776
     * @param $percentage
1777
     * @param bool $show_percentage
1778
     * @param null $extra_info
1779
     * @return string
1780
     */
1781
    public static function bar_progress($percentage, $show_percentage = true, $extra_info = null)
1782
    {
1783
        $percentage = intval($percentage);
1784
        $div = '<div class="progress">
1785
                <div
1786
                    class="progress-bar progress-bar-striped"
1787
                    role="progressbar"
1788
                    aria-valuenow="'.$percentage.'"
1789
                    aria-valuemin="0"
1790
                    aria-valuemax="100"
1791
                    style="width: '.$percentage.'%;"
1792
                >';
1793
        if ($show_percentage) {
1794
            $div .= $percentage.'%';
1795
        } else {
1796
            if (!empty($extra_info)) {
1797
                $div .= $extra_info;
1798
            }
1799
        }
1800
        $div .= '</div>';
1801
1802
        return $div;
1803
    }
1804
1805
    /**
1806
     * @param string $count
1807
     * @param string $type
1808
     * @return null|string
1809
     */
1810
    public static function badge($count, $type ="warning")
1811
    {
1812
        $class = '';
1813
1814
        switch ($type) {
1815
            case 'success':
1816
                $class = 'badge-success';
1817
                break;
1818
            case 'warning':
1819
                $class = 'badge-warning';
1820
                break;
1821
            case 'important':
1822
                $class = 'badge-important';
1823
                break;
1824
            case 'info':
1825
                $class = 'badge-info';
1826
                break;
1827
            case 'inverse':
1828
                $class = 'badge-inverse';
1829
                break;
1830
        }
1831
1832
        if (!empty($count)) {
1833
            return ' <span class="badge '.$class.'">'.$count.'</span>';
1834
        }
1835
        return null;
1836
    }
1837
1838
    /**
1839
     * @param array $badge_list
1840
     * @return string
1841
     */
1842
    public static function badge_group($badge_list)
1843
    {
1844
        $html = '<div class="badge-group">';
1845
        foreach ($badge_list as $badge) {
1846
            $html .= $badge;
1847
        }
1848
        $html .= '</div>';
1849
        return $html;
1850
    }
1851
1852
    /**
1853
     * @param string $content
1854
     * @param string $type
1855
     * @return string
1856
     */
1857
    public static function label($content, $type = 'default')
1858
    {
1859
        switch ($type) {
1860
            case 'success':
1861
                $class = 'label-success';
1862
                break;
1863
            case 'warning':
1864
                $class = 'label-warning';
1865
                break;
1866
            case 'important':
1867
                //no break
1868
            case 'danger':
1869
                $class = 'label-danger';
1870
                break;
1871
            case 'info':
1872
                $class = 'label-info';
1873
                break;
1874
            case 'primary':
1875
                $class = 'label-primary';
1876
                break;
1877
            default:
1878
                $class = 'label-default';
1879
                break;
1880
        }
1881
1882
        $html = '';
1883
        if (!empty($content)) {
1884
            $html = '<span class="label '.$class.'">';
1885
            $html .= $content;
1886
            $html .='</span>';
1887
        }
1888
1889
        return $html;
1890
    }
1891
1892
    /**
1893
     * @param array $items
1894
     * @return null|string
1895
     */
1896
    public static function actions($items, $class = 'new_actions')
1897
    {
1898
        $html = null;
1899
        if (!empty($items)) {
1900
            $html = '<div class="'.$class.'"><ul class="nav nav-pills">';
1901
            foreach ($items as $value) {
1902
                $class = null;
1903
                if (isset($value['active']) && $value['active']) {
1904
                    $class = 'class ="active"';
1905
                }
1906
1907
                if (basename($_SERVER['REQUEST_URI']) == basename($value['url']) ) {
1908
                    $class = 'class ="active"';
1909
                }
1910
                $html .= "<li $class >";
1911
                $attributes = isset($value['url_attributes']) ? $value['url_attributes'] : array();
1912
                $html .= self::url($value['content'], $value['url'], $attributes);
1913
                $html .= '</li>';
1914
            }
1915
            $html .= '</ul></div>';
1916
        }
1917
        return $html;
1918
    }
1919
1920
    /**
1921
     * Prints a tooltip
1922
     * @param string $text
1923
     * @param string $tip
1924
     *
1925
     * @return string
1926
     */
1927
    public static function tip($text, $tip)
1928
    {
1929
        if (empty($tip)) {
1930
            return $text;
1931
        }
1932
        return self::span($text, array('class' => 'boot-tooltip', 'title' => strip_tags($tip)));
1933
    }
1934
1935
    /**
1936
     * @param array $items
1937
     * @param string $type
1938
     * @param null $id
1939
     * @return null|string
1940
     */
1941
    public static function generate_accordion($items, $type = 'jquery', $id = null)
1942
    {
1943
        $html = null;
1944
        if (!empty($items)) {
1945
            if (empty($id)) {
1946
                $id = api_get_unique_id();
1947
            }
1948
            if ($type == 'jquery') {
1949
                $html = '<div class="accordion_jquery" id="'.$id.'">'; //using jquery
1950
            } else {
1951
                $html = '<div class="accordion" id="'.$id.'">'; //using bootstrap
1952
            }
1953
1954
            $count = 1;
1955
            foreach ($items as $item) {
1956
                $html .= '<div class="accordion-my-group">';
1957
                $html .= '<div class="accordion-heading">
1958
                            <a class="accordion-toggle" data-toggle="collapse" data-parent="#'.$id.'" href="#collapse'.$count.'">
1959
                            '.$item['title'].'
1960
                            </a>
1961
                          </div>';
1962
1963
                $html .= '<div id="collapse'.$count.'" class="accordion-body">';
1964
                $html .= '<div class="accordion-my-inner">
1965
                            '.$item['content'].'
1966
                            </div>
1967
                          </div>';
1968
            }
1969
            $html .= '</div>';
1970
        }
1971
1972
        return $html;
1973
    }
1974
1975
    /**
1976
     * @todo use twig
1977
     */
1978
    public static function group_button($title, $elements)
1979
    {
1980
        $html = '<div class="btn-group">
1981
                <button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
1982
                '.$title.'
1983
                <span class="caret"></span></button>
1984
                <ul class="dropdown-menu">';
1985
        foreach ($elements as $item) {
1986
            $html .= Display::tag('li', Display::url($item['title'], $item['href']));
1987
        }
1988
        $html .= '</ul>
1989
            </div>';
1990
        return $html;
1991
    }
1992
1993
    /**
1994
     * @param string $file
1995
     * @param array $params
1996
     * @return null|string
1997
     */
1998
    public static function getMediaPlayer($file, $params = array())
1999
    {
2000
        $fileInfo = pathinfo($file);
2001
2002
        switch ($fileInfo['extension']) {
2003
            case 'wav':
2004
                if (isset($params['url'])) {
2005
                    $url = DocumentManager::generateAudioTempFile(basename($file), $file);
2006
                    return DocumentManager::readNanogongFile($url);
2007
                }
2008
                break;
2009
            case 'mp3':
2010
            case 'webm':
2011
                $autoplay = null;
2012
                if (isset($params['autoplay']) && $params['autoplay'] == 'true') {
2013
                    $autoplay = 'autoplay';
2014
                }
2015
                $width = isset($params['width']) ? 'width="'.$params['width'].'"' : null;
2016
                $id = isset($params['id']) ? $params['id'] : $fileInfo['basename'];
2017
                $class = isset($params['class']) ? ' class="'.$params['class'].'"' : null;
2018
2019
                $html = '<audio id="'.$id.'" '.$class.' controls '.$autoplay.' '.$width.' src="'.$params['url'].'" >';
2020
                $html .= '<object width="'.$width.'" height="50" type="application/x-shockwave-flash" data="'.api_get_path(WEB_LIBRARY_PATH).'javascript/mediaelement/flashmediaelement.swf">
2021
                            <param name="movie" value="'.api_get_path(WEB_LIBRARY_PATH).'javascript/mediaelement/flashmediaelement.swf" />
2022
                            <param name="flashvars" value="controls=true&file='.$params['url'].'" />
2023
                          </object>';
2024
                $html .= '</audio>';
2025
2026
                return $html;
2027
                break;
2028
        }
2029
2030
        return null;
2031
    }
2032
2033
    /**
2034
     *
2035
     * @param int $nextValue
2036
     * @param array $list
2037
     * @param int $current
2038
     * @param int $fixedValue
2039
     * @param array $conditions
2040
     * @param string $link
2041
     * @param bool $isMedia
2042
     * @param bool $addHeaders
2043
     * @return string
2044
     */
2045
    public static function progressPaginationBar(
2046
        $nextValue,
2047
        $list,
2048
        $current,
2049
        $fixedValue = null,
2050
        $conditions = array(),
2051
        $link = null,
2052
        $isMedia = false,
2053
        $addHeaders = true,
2054
        $linkAttributes = array()
2055
    ) {
2056
        if ($addHeaders) {
2057
            $pagination_size = 'pagination-mini';
2058
            $html = '<div class="exercise_pagination pagination '.$pagination_size.'"><ul>';
2059
        } else {
2060
            $html = null;
2061
        }
2062
        $affectAllItems = false;
2063
        if ($isMedia && isset($fixedValue) && ($nextValue + 1 == $current)) {
2064
            $affectAllItems = true;
2065
        }
2066
        $localCounter = 0;
2067
        foreach ($list as $itemId) {
2068
            $isCurrent = false;
2069
            if ($affectAllItems) {
2070
                $isCurrent = true;
2071
            } else {
2072
                if (!$isMedia) {
2073
                    $isCurrent = $current == ($localCounter + $nextValue + 1) ? true : false;
2074
                }
2075
            }
2076
            $html .= self::parsePaginationItem(
2077
                $itemId,
2078
                $isCurrent,
2079
                $conditions,
2080
                $link,
2081
                $nextValue,
2082
                $isMedia,
2083
                $localCounter,
2084
                $fixedValue,
2085
                $linkAttributes
2086
            );
2087
            $localCounter++;
2088
        }
2089
        if ($addHeaders) {
2090
            $html .= '</ul></div>';
2091
        }
2092
        return $html;
2093
    }
2094
    /**
2095
     *
2096
     * @param int $itemId
2097
     * @param bool $isCurrent
2098
     * @param array $conditions
2099
     * @param string $link
2100
     * @param int $nextValue
2101
     * @param bool $isMedia
2102
     * @param int $localCounter
2103
     * @param int $fixedValue
2104
     * @return string
2105
     */
2106
    static function parsePaginationItem(
2107
        $itemId,
2108
        $isCurrent,
2109
        $conditions,
2110
        $link,
2111
        $nextValue = 0,
2112
        $isMedia = false,
2113
        $localCounter = null,
2114
        $fixedValue = null,
2115
        $linkAttributes = array())
2116
    {
2117
        $defaultClass = "before";
2118
        $class = $defaultClass;
2119
        foreach ($conditions as $condition) {
2120
            $array = isset($condition['items']) ? $condition['items'] : array();
2121
            $class_to_applied = $condition['class'];
2122
            $type = isset($condition['type']) ? $condition['type'] : 'positive';
2123
            $mode = isset($condition['mode']) ? $condition['mode'] : 'add';
2124
            switch ($type) {
2125 View Code Duplication
                case 'positive':
2126
                    if (in_array($itemId, $array)) {
2127
                        if ($mode == 'overwrite') {
2128
                            $class = " $defaultClass $class_to_applied";
2129
                        } else {
2130
                            $class .= " $class_to_applied";
2131
                        }
2132
                    }
2133
                    break;
2134 View Code Duplication
                case 'negative':
2135
                    if (!in_array($itemId, $array)) {
2136
                        if ($mode == 'overwrite') {
2137
                            $class = " $defaultClass $class_to_applied";
2138
                        } else {
2139
                            $class .= " $class_to_applied";
2140
                        }
2141
                    }
2142
                    break;
2143
            }
2144
        }
2145
        if ($isCurrent) {
2146
            $class = "before current";
2147
        }
2148
        if ($isMedia && $isCurrent) {
2149
            $class = "before current";
2150
        }
2151
        if (empty($link)) {
2152
            $link_to_show = "#";
2153
        } else {
2154
            $link_to_show = $link.($nextValue + $localCounter);
2155
        }
2156
        $label = $nextValue + $localCounter + 1;
2157
        if ($isMedia) {
2158
            $label = ($fixedValue + 1) .' '.chr(97 + $localCounter);
2159
            $link_to_show = $link.$fixedValue.'#questionanchor'.$itemId;
2160
        }
2161
        $link = Display::url($label.' ', $link_to_show, $linkAttributes);
2162
        return  '<li class = "'.$class.'">'.$link.'</li>';
2163
    }
2164
    
2165
    /**
2166
     * @param int $current
2167
     * @param int $total
2168
     * @return string
2169
     */
2170
    public static function paginationIndicator($current, $total)
2171
    {
2172
        $html = null;
2173
        if (!empty($current) && !empty($total)) {
2174
            $label = sprintf(get_lang('PaginationXofY'), $current, $total);
2175
            $html = self::url($label, '#', array('class' => 'btn disabled'));
2176
        }
2177
        return $html;
2178
    }
2179
2180
    /**
2181
     * Adds a message in the queue
2182
     * @param string $message
2183
     */
2184
    public static function addFlash($message)
2185
    {
2186
        $messages = Session::read('flash_messages');
2187
        if (empty($messages)) {
2188
            $messages[] = $message;
2189
        } else {
2190
            array_push($messages, $message);
2191
        }
2192
        Session::write('flash_messages', $messages);
2193
    }
2194
2195
    /**
2196
     * @return string
2197
     */
2198
    public static function getFlashToString()
2199
    {
2200
        $messages = Session::read('flash_messages');
2201
        $messageToString = '';
2202
        if (!empty($messages)) {
2203
            foreach ($messages as $message) {
2204
                $messageToString .= $message;
2205
            }
2206
        }
2207
2208
        return $messageToString;
2209
    }
2210
2211
    /**
2212
     * Shows the message from the session
2213
     */
2214
    public static function showFlash()
2215
    {
2216
        echo self::getFlashToString();
2217
    }
2218
2219
    /**
2220
     * Destroys the message session
2221
     */
2222
    public static function cleanFlashMessages()
2223
    {
2224
        Session::erase('flash_messages');
2225
    }
2226
2227
    /**
2228
     * Get the profile edition link for a user
2229
     * @param int $userId The user id
2230
     * @param boolean $asAdmin Optional. Whether get the URL for the platform admin
2231
     * @return string The link
2232
     */
2233
    public static function getProfileEditionLink($userId, $asAdmin = false)
2234
    {
2235
        $editProfileUrl = api_get_path(WEB_CODE_PATH).'auth/profile.php';
2236
2237
        if ($asAdmin) {
2238
            $editProfileUrl = api_get_path(WEB_CODE_PATH)."admin/user_edit.php?user_id=".intval($userId);
2239
        }
2240
2241
        if (api_get_setting('sso_authentication') === 'true') {
2242
            $subSSOClass = api_get_setting('sso_authentication_subclass');
2243
2244
            $objSSO = null;
2245
2246 View Code Duplication
            if (!empty($subSSOClass)) {
2247
                require_once api_get_path(SYS_CODE_PATH)."auth/sso/sso.$subSSOClass.class.php";
2248
                $subSSOClass = 'sso'.$subSSOClass;
2249
                $objSSO = new $subSSOClass();
2250
            } else {
2251
                $objSSO = new sso();
2252
            }
2253
2254
            $editProfileUrl = $objSSO->generateProfileEditingURL(
2255
                $userId,
2256
                $asAdmin
2257
            );
2258
        }
2259
2260
        return $editProfileUrl;
2261
    }
2262
2263
    /**
2264
     * Get the vCard for a user
2265
     * @param int $userId The user id
2266
     * @return string *.*vcf file
2267
     */
2268
    public static function getVCardUserLink($userId)
2269
    {
2270
        $vCardUrl = api_get_path(WEB_PATH).'main/social/vcard_export.php?userId='.intval($userId);;
2271
2272
        return $vCardUrl;
2273
    }
2274
2275
    /**
2276
     * @param string $content
2277
     * @param string $title
2278
     * @param string $footer
2279
     * @param string $style primary|success|info|warning|danger
2280
     * @param string $extra
2281
     *
2282
     * @return string
2283
     */
2284
    public static function panel($content, $title = '', $footer = '', $style = '', $extra = '')
2285
    {
2286
        $title = !empty($title) ? '<div class="panel-heading"><h3 class="panel-title">'.$title.'</h3>'.$extra.'</div>' : '';
2287
        $footer = !empty($footer) ? '<div class="panel-footer ">'.$footer.'</div>' : '';
2288
        $styles = ['primary','success','info','warning','danger'];
2289
        $style = !in_array($style, $styles) ? 'default' : $style;
2290
2291
        return '
2292
            <div class="panel panel-'.$style.'">
2293
                '.$title.'
2294
                '.self::contentPanel($content).'
2295
                '.$footer.'
2296
            </div>'
2297
        ;
2298
    }
2299
2300
    /**
2301
     * @param string $content
2302
     * @return string
2303
     */
2304
    public static function contentPanel($content)
2305
    {
2306
        return '<div class="panel-body">
2307
                '.$content.'
2308
                </div>';
2309
    }
2310
2311
    /**
2312
     * Get the button HTML with an Awesome Font icon
2313
     * @param string $text The button content
2314
     * @param string $url The url to button
2315
     * @param string $icon The Awesome Font class for icon
2316
     * @param string $type Optional. The button Bootstrap class. Default 'default' class
2317
     * @param array $attributes The additional attributes
2318
     * @return string The button HTML
2319
     */
2320
    public static function toolbarButton(
2321
        $text,
2322
        $url,
2323
        $icon = 'check',
2324
        $type = 'default',
2325
        array $attributes = [],
2326
        $includeText = true
2327
    ) {
2328
        $buttonClass = "btn btn-$type";
2329
        $icon = self::tag('i', null, ['class' => "fa fa-$icon fa-fw", 'aria-hidden' => 'true']);
2330
        $attributes['class'] = isset($attributes['class']) ? "$buttonClass {$attributes['class']}" : $buttonClass;
2331
2332
        if (!$includeText) {
2333
            $text = '<span class="sr-only">' . $text . '</span>';
2334
        }
2335
2336
        return self::url("$icon $text", $url, $attributes);
2337
    }
2338
2339
    /**
2340
     * @param int $id
2341
     * @param array $content
2342
     * @param int $col
2343
     * @param bool|true $right
2344
     * @return string
2345
     */
2346
    public static function toolbarAction($id, $content = array(), $col = 2, $right = true)
2347
    {
2348
        $columns = 12/$col;
2349
        $html = '';
2350
        $html .= '<div id="' . $id . '" class="actions">';
2351
        $html .= '<div class="row">';
2352
        if ($col > 4) {
2353
            $html = '<div class="alert alert-warning" role="alert">Action toolbar design does not work when exceeding four columns - check Display::toolbarAction()</div>';
2354
        } else {
2355
            for ( $i = 0; $i < $col; $i++ ) {
2356
                $html .= '<div class="col-md-' . $columns . '">';
2357
                if ( $col == 2 && $i == 1 ) {
2358
                    if ($right === true) {
2359
                        $html .= '<div class="pull-right">';
2360
                        $html .= (isset($content[$i]) ? $content[$i] : '');
2361
                        $html .= '</div>';
2362
                    } else {
2363
                        $html .= $content[$i];
2364
                    }
2365
                } else {
2366
                    $html .= $content[$i];
2367
                }
2368
                $html .= '</div>';
2369
            }
2370
        }
2371
        $html .= '</div>';
2372
        $html .= '</div>';
2373
2374
        return $html;
2375
    }
2376
2377
    /**
2378
     * Get a HTML code for a icon by Font Awesome
2379
     * @param string $name The icon name
2380
     * @param boolean $fixWidth Optional. Whether add the fw class
2381
     * @param int|string $size Optional. The size for the icon.
2382
     * @param string $additionalClass Optional. Additional class
2383
     *
2384
     * @return string
2385
     */
2386
    public static function returnFontAwesomeIcon(
2387
        $name,
2388
        $fixWidth = false,
2389
        $size = null,
2390
        $additionalClass = null
2391
    ) {
2392
        $className = "fa fa-$name";
2393
2394
        if ($fixWidth) {
2395
            $className .= ' fa-fw';
2396
        }
2397
2398
        switch ($size) {
2399
            case 'lg':
2400
                $className .= ' fa-lg';
2401
                break;
2402
            case 2:
2403
                //no break
2404
            case 3:
2405
                //no break
2406
            case 4:
2407
                //no break
2408
            case 5:
2409
                $className .= " fa-{$size}x";
2410
                break;
2411
        }
2412
2413
        if (!empty($additionalClass)) {
2414
            $className .= " $additionalClass";
2415
        }
2416
2417
        $icon = self::tag('em', null, ['class' => $className]);
2418
2419
        return "$icon ";
2420
    }
2421
2422
    /**
2423
     * @param string $title
2424
     * @param string $content
2425
     * @param null $id
2426
     * @param array $params
2427
     * @param null $idAccordion
2428
     * @param null $idCollapse
2429
     * @param bool|true $open
2430
     * @param bool|false $fullClickable
2431
     * @return null|string
2432
     */
2433
    public static function panelCollapse(
2434
        $title,
2435
        $content,
2436
        $id = null,
2437
        $params = array(),
2438
        $idAccordion = null,
2439
        $idCollapse = null,
2440
        $open = true,
2441
        $fullClickable = false
2442
    ) {
2443
        if (!empty($idAccordion)) {
2444
            $headerClass = '';
2445
            $headerClass .= $fullClickable ? 'center-block ' : '';
2446
            $headerClass .= $open ? '' : 'collapsed';
2447
            $contentClass = 'panel-collapse collapse ';
2448
            $contentClass .= $open ? 'in' : '';
2449
            $ariaExpanded = $open ? 'true' : 'false';
2450
2451
            $html = <<<HTML
2452
                <div class="panel-group" id="$idAccordion" role="tablist" aria-multiselectable="true">
2453
                    <div class="panel panel-default" id="$id">
2454
                        <div class="panel-heading" role="tab">
2455
                            <h4 class="panel-title">
2456
                                <a class="$headerClass" role="button" data-toggle="collapse" data-parent="#$idAccordion" href="#$idCollapse" aria-expanded="$ariaExpanded" aria-controls="$idCollapse">$title</a>
2457
                            </h4>
2458
                        </div>
2459
                        <div id="$idCollapse" class="$contentClass" role="tabpanel">
2460
                            <div class="panel-body">$content</div>
2461
                        </div>
2462
                    </div>
2463
                </div>
2464
HTML;
2465 View Code Duplication
        } else {
2466
            if (!empty($id)) {
2467
                $params['id'] = $id;
2468
            }
2469
            $params['class'] = 'panel panel-default';
2470
            $html = null;
2471
            if (!empty($title)) {
2472
                $html .= '<div class="panel-heading">'.$title.'</div>' . PHP_EOL;
2473
            }
2474
            $html.= '<div class="panel-body">'.$content.'</div>' . PHP_EOL;
2475
            $html = Display::div($html, $params);
2476
        }
2477
        return $html;
2478
    }
2479
}
2480