Passed
Push — 1.10.x ( f38c8d...0458c3 )
by
unknown
144:03 queued 91:39
created

Display::return_icon()   F

Complexity

Conditions 15
Paths 416

Size

Total Lines 78
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 78
rs 3.8126
cc 15
eloc 46
nc 416
nop 7

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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