Completed
Push — master ( f5c42a...6861f5 )
by Julito
75:53 queued 27:38
created

Display::display_footer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use ChamiloSession as Session;
5
use Chamilo\CoreBundle\Entity\ExtraField;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, ExtraField.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
6
use Chamilo\CoreBundle\Framework\Container;
7
8
/**
9
 * Class Display
10
 * Contains several public functions dealing with the display of
11
 * table data, messages, help topics, ...
12
 *
13
 * Include/require it in your code to use its public functionality.
14
 * There are also several display public functions in the main api library.
15
 *
16
 * All public functions static public functions inside a class called Display,
17
 * so you use them like this: e.g.
18
 * Display::display_normal_message($message)
19
 *
20
 * @package chamilo.library
21
 *
22
 */
23
class Display
24
{
25
    /** @var Template */
26
    public static $global_template;
27
    public static $preview_style = null;
28
29
    /**
30
     * Constructor
31
     */
32
    public function __construct()
33
    {
34
    }
35
36
    /**
37
     * @return array
38
     */
39
    public static function toolList()
40
    {
41
        return array(
42
            'group',
43
            'work',
44
            'glossary',
45
            'forum',
46
            'course_description',
47
            'gradebook',
48
            'attendance',
49
            'course_progress',
50
            'notebook'
51
        );
52
    }
53
54
     /**
55
     * Displays the page header
56
     * @param string The name of the page (will be showed in the page title)
57
     * @param string Optional help file name
58
     * @param string $page_header
59
     */
60
    public static function display_header($tool_name ='', $help = null, $page_header = null)
61
    {
62
        $origin = api_get_origin();
63
        $showHeader = true;
64
        if (isset($origin) && $origin == 'learnpath') {
65
            $showHeader = false;
66
        }
67
68
        self::$global_template = new Template($tool_name, $showHeader, $showHeader);
69
70
71
        // Fixing tools with any help it takes xxx part of main/xxx/index.php
72
        if (empty($help)) {
73
            $currentURL = api_get_self();
74
            preg_match('/main\/([^*\/]+)/', $currentURL, $matches);
75
            $toolList = self::toolList();
76
            if (!empty($matches)) {
77
                foreach ($matches as $match) {
78
                    if (in_array($match, $toolList)) {
79
                        $help = explode('_', $match);
80
                        $help = array_map('ucfirst', $help);
81
                        $help = implode('', $help);
82
                        break;
83
                    }
84
                }
85
            }
86
        }
87
88
        self::$global_template->setHelp($help);
89
        if (!empty(self::$preview_style)) {
90
            self::$global_template->preview_theme = self::$preview_style;
91
            self::$global_template->setCssFiles();
92
            self::$global_template->set_js_files();
93
            self::$global_template->setCssCustomFiles();
94
        }
95
96
        if (!empty($page_header)) {
97
            self::$global_template->assign('header', $page_header);
98
        }
99
100
        echo self::$global_template->show_header_template();
101
    }
102
103
    /**
104
     * Displays the reduced page header (without banner)
105
     */
106
    public static function display_reduced_header()
107
    {
108
        global $show_learnpath, $tool_name;
109
        self::$global_template = new Template($tool_name, false, false, $show_learnpath);
110
        echo self::$global_template->show_header_template();
111
    }
112
113
    /**
114
     * Display no header
115
     */
116
    public static function display_no_header()
117
    {
118
        global $tool_name, $show_learnpath;
119
        $disable_js_and_css_files = true;
120
        self::$global_template = new Template($tool_name, false, false, $show_learnpath);
121
    }
122
123
    /**
124
     * Displays the reduced page header (without banner)
125
     */
126
    public static function set_header()
127
    {
128
        global $show_learnpath, $tool_name;
129
        self::$global_template = new Template($tool_name, false, false, $show_learnpath);
130
    }
131
132
    /**
133
     * Display the page footer
134
     */
135
    public static function display_footer()
136
    {
137
        echo self::$global_template->show_footer_template();
138
    }
139
140
    /**
141
     * Display the page footer
142
     */
143
    public static function display_reduced_footer()
144
    {
145
        echo self::$global_template->show_footer_js_template();
146
        echo '</body></html>';
147
    }
148
149
    public static function page()
150
    {
151
        return new Page();
152
    }
153
154
    /**
155
     * Displays the tool introduction of a tool.
156
     *
157
     * @author Patrick Cool <[email protected]>, Ghent University
158
     * @param string $tool These are the constants that are used for indicating the tools.
159
     * @param array $editor_config Optional configuration settings for the online editor.
160
     * return: $tool return a string array list with the "define" in main_api.lib
161
     * @return html code for adding an introduction
162
     */
163
    public static function display_introduction_section($tool, $editor_config = null)
164
    {
165
        echo self::return_introduction_section($tool, $editor_config);
166
    }
167
168
    /**
169
     * @param string $tool
170
     * @param array $editor_config
171
     * @return null
172
     */
173
    public static function return_introduction_section($tool, $editor_config = null)
174
    {
175
        $is_allowed_to_edit = api_is_allowed_to_edit();
176
        $moduleId = $tool;
177
        if (api_get_setting('enable_tool_introduction') == 'true' || $tool == TOOL_COURSE_HOMEPAGE) {
178
            $introduction_section = null;
179
            require api_get_path(SYS_INC_PATH).'introductionSection.inc.php';
180
            return $introduction_section;
181
        }
182
    }
183
184
    /**
185
     *	Displays a localised html file
186
     *	tries to show the file "$full_file_name"."_".$language_interface.".html"
187
     *	and if this does not exist, shows the file "$full_file_name".".html"
188
     *	warning this public function defines a global
189
     *	@param $full_file_name, the (path) name of the file, without .html
190
     *	@return return a string with the path
191
     */
192
    public static function display_localised_html_file($full_file_name)
193
    {
194
        global $language_interface;
195
        $localised_file_name = $full_file_name.'_'.$language_interface.'.html';
196
        $default_file_name = $full_file_name.'.html';
197
        if (file_exists($localised_file_name)) {
198
            include $localised_file_name;
199
        } else {
200
            include $default_file_name;
201
        }
202
    }
203
204
    /**
205
     * Displays a table
206
     * @param array $header Titles for the table header
207
     * 						each item in this array can contain 3 values
208
     * 						- 1st element: the column title
209
     * 						- 2nd element: true or false (column sortable?)
210
     * 						- 3th element: additional attributes for
211
     *  						th-tag (eg for column-width)
212
     * 						- 4the element: additional attributes for the td-tags
213
     * @param array $content 2D-array with the tables content
214
     * @param array $sorting_options Keys are:
215
     * 					'column' = The column to use as sort-key
216
     * 					'direction' = SORT_ASC or SORT_DESC
217
     * @param array $paging_options Keys are:
218
     * 					'per_page_default' = items per page when switching from
219
     * 										 full-	list to per-page-view
220
     * 					'per_page' = number of items to show per page
221
     * 					'page_nr' = The page to display
222
     * @param array $query_vars Additional variables to add in the query-string
223
     * @param string The style that the table will show. You can set 'table' or 'grid'
224
     * @author [email protected]
225
     */
226
    public static function display_sortable_table(
227
        $header,
228
        $content,
229
        $sorting_options = array(),
230
        $paging_options = array(),
231
        $query_vars = null,
232
        $form_actions = array(),
233
        $style = 'table'
234
    ) {
235
        global $origin;
236
        $column = isset($sorting_options['column']) ? $sorting_options['column'] : 0;
237
        $default_items_per_page = isset($paging_options['per_page']) ? $paging_options['per_page'] : 20;
238
        $table = new SortableTableFromArray($content, $column, $default_items_per_page);
239
        if (is_array($query_vars)) {
240
            $table->set_additional_parameters($query_vars);
241
        }
242
        if ($style == 'table') {
243
            if (is_array($header) && count($header) > 0) {
244
                foreach ($header as $index => $header_item) {
245
                    $table->set_header(
246
                        $index,
247
                        isset($header_item[0]) ? $header_item[0] : null,
248
                        isset($header_item[1]) ? $header_item[1] : null,
249
                        isset($header_item[2]) ? $header_item[2] : null,
250
                        isset($header_item[3]) ? $header_item[3] : null
251
                    );
252
                }
253
            }
254
            $table->set_form_actions($form_actions);
255
            $table->display();
256
        } else {
257
            $table->display_grid();
258
        }
259
    }
260
261
    public static function return_sortable_table(
262
        $header,
263
        $content,
264
        $sorting_options = array(),
265
        $paging_options = array(),
266
        $query_vars = null,
267
        $form_actions = array(),
268
        $style = 'table'
269
    ) {
270
        ob_start();
271
        self::display_sortable_table(
272
            $header,
273
            $content,
274
            $sorting_options,
275
            $paging_options,
276
            $query_vars,
277
            $form_actions,
278
            $style
279
        );
280
        $content = ob_get_contents();
281
        ob_end_clean();
282
        return $content;
283
    }
284
285
    /**
286
     * Shows a nice grid
287
     * @param string grid name (important to create css)
288
     * @param array header content
289
     * @param array array with the information to show
290
     * @param array $paging_options Keys are:
291
     * 					'per_page_default' = items per page when switching from
292
     * 										 full-	list to per-page-view
293
     * 					'per_page' = number of items to show per page
294
     * 					'page_nr' = The page to display
295
     * 					'hide_navigation' =  true to hide the navigation
296
     * @param array $query_vars Additional variables to add in the query-string
297
     * @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...
298
     * @param mixed An array with bool values to know which columns show.
299
     * i.e: $visibility_options= array(true, false) we will only show the first column
300
     * 				Can be also only a bool value. TRUE: show all columns, FALSE: show nothing
301
     */
302
    public static function display_sortable_grid(
303
        $name,
304
        $header,
305
        $content,
306
        $paging_options = array(),
307
        $query_vars = null,
308
        $form_actions = array(),
309
        $visibility_options = true,
310
        $sort_data = true,
311
        $grid_class = array()
312
    ) {
313
        echo self::return_sortable_grid(
314
            $name,
315
            $header,
316
            $content,
317
            $paging_options,
318
            $query_vars,
319
            $form_actions,
320
            $visibility_options,
321
            $sort_data,
322
            $grid_class
323
        );
324
    }
325
326
    /**
327
     * Gets a nice grid in html string
328
     * @param string grid name (important to create css)
329
     * @param array header content
330
     * @param array array with the information to show
331
     * @param array $paging_options Keys are:
332
     * 					'per_page_default' = items per page when switching from
333
     * 										 full-	list to per-page-view
334
     * 					'per_page' = number of items to show per page
335
     * 					'page_nr' = The page to display
336
     * 					'hide_navigation' =  true to hide the navigation
337
     * @param array $query_vars Additional variables to add in the query-string
338
     * @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...
339
     * @param mixed An array with bool values to know which columns show. i.e:
340
     *  $visibility_options= array(true, false) we will only show the first column
341
     * 	Can be also only a bool value. TRUE: show all columns, FALSE: show nothing
342
     * @param bool  true for sorting data or false otherwise
343
     * @param array grid classes
344
     * @return 	string   html grid
345
     */
346
    public static function return_sortable_grid(
347
        $name,
348
        $header,
349
        $content,
350
        $paging_options = array(),
351
        $query_vars = null,
352
        $form_actions = array(),
353
        $visibility_options = true,
354
        $sort_data = true,
355
        $grid_class = array(),
356
        $elementCount = 0
357
    ) {
358
        $column =  0;
359
        $default_items_per_page = isset($paging_options['per_page']) ? $paging_options['per_page'] : 20;
360
361
        $table = new SortableTableFromArray($content, $column, $default_items_per_page, $name);
362
        $table->total_number_of_items = intval($elementCount);
363
        if (is_array($query_vars)) {
364
            $table->set_additional_parameters($query_vars);
365
        }
366
367
        return $table->display_simple_grid(
368
            $visibility_options,
369
            $paging_options['hide_navigation'],
370
            $default_items_per_page,
371
            $sort_data,
372
            $grid_class
373
        );
374
    }
375
376
    /**
377
     * Displays a table with a special configuration
378
     * @param array $header Titles for the table header
379
     * 						each item in this array can contain 3 values
380
     * 						- 1st element: the column title
381
     * 						- 2nd element: true or false (column sortable?)
382
     * 						- 3th element: additional attributes for
383
     *  						th-tag (eg for column-width)
384
     * 						- 4the element: additional attributes for the td-tags
385
     * @param array $content 2D-array with the tables content
386
     * @param array $sorting_options Keys are:
387
     * 					'column' = The column to use as sort-key
388
     * 					'direction' = SORT_ASC or SORT_DESC
389
     * @param array $paging_options Keys are:
390
     * 					'per_page_default' = items per page when switching from
391
     * 										 full-	list to per-page-view
392
     * 					'per_page' = number of items to show per page
393
     * 					'page_nr' = The page to display
394
     * @param array $query_vars Additional variables to add in the query-string
395
     * @param array $column_show Array of binaries 1= show columns 0. hide a column
396
     * @param array $column_order An array of integers that let us decide how the columns are going to be sort.
397
     * 						      i.e:  $column_order=array('1''4','3','4'); The 2nd column will be order like the 4th column
398
     * @param array $form_actions Set optional forms actions
399
     *
400
     * @author Julio Montoya
401
     */
402
    public static function display_sortable_config_table(
403
        $table_name,
404
        $header,
405
        $content,
406
        $sorting_options = array(),
407
        $paging_options = array(),
408
        $query_vars = null,
409
        $column_show = array(),
410
        $column_order = array(),
411
        $form_actions = array()
412
    ) {
413
        $column = isset($sorting_options['column']) ? $sorting_options['column'] : 0;
414
        $default_items_per_page = isset($paging_options['per_page']) ? $paging_options['per_page'] : 20;
415
416
        $table = new SortableTableFromArrayConfig(
417
            $content,
418
            $column,
419
            $default_items_per_page,
420
            $table_name,
421
            $column_show,
422
            $column_order
423
        );
424
425
        if (is_array($query_vars)) {
426
            $table->set_additional_parameters($query_vars);
427
        }
428
        // Show or hide the columns header
429
        if (is_array($column_show)) {
430
            for ($i = 0; $i < count($column_show); $i++) {
431
                if (!empty($column_show[$i])) {
432
                    $val0 = isset($header[$i][0]) ? $header[$i][0] : null;
433
                    $val1 = isset($header[$i][1]) ? $header[$i][1] : null;
434
                    $val2 = isset($header[$i][2]) ? $header[$i][2] : null;
435
                    $val3 = isset($header[$i][3]) ? $header[$i][3] : null;
436
                    $table->set_header($i, $val0, $val1, $val2, $val3);
437
                }
438
            }
439
        }
440
        $table->set_form_actions($form_actions);
441
        $table->display();
442
    }
443
444
    /**
445
     * Displays a normal message. It is recommended to use this public function
446
     * to display any normal information messages.
447
     * @param string $message
448
     * @param bool	$filter (true) or not (false)
449
     * @param bool $returnValue
450
     *
451
     * @deprecated use Display::addFlash with Display::return_message($message, 'normal');
452
     *
453
     * @return void
454
     */
455 View Code Duplication
    public static function display_normal_message($message, $filter = true, $returnValue = false)
456
    {
457
    	$message = self::return_message($message, 'normal', $filter);
458
        if ($returnValue) {
459
            return $message;
460
        } else {
461
            echo $message;
462
        }
463
    }
464
465
    /**
466
     * Displays an warning message. Use this if you want to draw attention to something
467
     * This can also be used for instance with the hint in the exercises
468
     *
469
     * @deprecated use Display::addFlash with Display::return_message
470
     */
471 View Code Duplication
    public static function display_warning_message($message, $filter = true, $returnValue = false)
472
    {
473
        $message = self::return_message($message, 'warning', $filter);
474
        if ($returnValue) {
475
            return $message;
476
        } else {
477
            echo $message;
478
        }
479
    }
480
481
    /**
482
     * Displays an confirmation message. Use this if something has been done successfully
483
     * @param bool	Filter (true) or not (false)
484
     * @deprecated use Display::addFlash with Display::return_message
485
     * @return void
486
     */
487 View Code Duplication
    public static function display_confirmation_message ($message, $filter = true, $returnValue = false)
488
    {
489
        $message = self::return_message($message, 'confirm', $filter);
490
        if ($returnValue) {
491
            return $message;
492
        } else {
493
            echo $message;
494
        }
495
    }
496
497
    /**
498
     * Displays an error message. It is recommended to use this public function if an error occurs
499
     * @param string $message - include any additional html
500
     *                          tags if you need them
501
     * @param bool	Filter (true) or not (false)
502
     * @deprecated use Display::addFlash with Display::return_message
503
     *
504
     * @return void
505
     */
506 View Code Duplication
    public static function display_error_message ($message, $filter = true, $returnValue = false)
507
    {
508
        $message = self::return_message($message, 'error', $filter);
509
        if ($returnValue) {
510
            return $message;
511
        } else {
512
            echo $message;
513
        }
514
    }
515
516
    /**
517
     * @param string $message
518
     * @param string $type
519
     * @param bool $filter
520
     */
521
    public static function return_message_and_translate($message, $type='normal', $filter = true)
522
    {
523
        $message = get_lang($message);
524
        echo self::return_message($message, $type, $filter);
525
    }
526
527
    /**
528
     * Returns a div html string with
529
     * @param   string  $message
530
     * @param   string  $type Example: confirm, normal, warning, error
531
     * @param   bool    $filter Whether to XSS-filter or not
532
     * @return  string  Message wrapped into an HTML div
533
     */
534
    public static function return_message($message, $type = 'normal', $filter = true)
535
    {
536
        if (empty($message)) {
537
            return '';
538
        }
539
540
        if ($filter) {
541
        	$message = api_htmlentities($message, ENT_QUOTES, api_is_xml_http_request() ? 'UTF-8' : api_get_system_encoding());
542
        }
543
544
        $class = '';
545
        switch ($type) {
546
            case 'warning':
547
               $class .= 'alert alert-warning';
548
               break;
549
            case 'error':
550
               $class .= 'alert alert-danger';
551
               break;
552
            case 'confirmation':
553
            case 'confirm':
554
            case 'success':
555
                $class .= 'alert alert-success';
556
               break;
557
            case 'normal':
558
            default:
559
                $class .= 'alert alert-info';
560
        }
561
562
        return self::div($message, array('class'=> $class));
563
    }
564
565
    /**
566
     * Returns an encrypted mailto hyperlink
567
     *
568
     * @param string  e-mail
569
     * @param string  clickable text
570
     * @param string  optional, class from stylesheet
571
     * @return string encrypted mailto hyperlink
572
     */
573
    public static function encrypted_mailto_link($email, $clickable_text = null, $style_class = '')
574
    {
575
        if (is_null($clickable_text)) {
576
            $clickable_text = $email;
577
        }
578
        // "mailto:" already present?
579
        if (substr($email, 0, 7) != 'mailto:') {
580
            $email = 'mailto:'.$email;
581
        }
582
        // Class (stylesheet) defined?
583
        if ($style_class != '') {
584
            $style_class = ' class="'.$style_class.'"';
585
        }
586
        // Encrypt email
587
        $hmail = '';
588 View Code Duplication
        for ($i = 0; $i < strlen($email); $i ++) {
589
            $hmail .= '&#'.ord($email {
590
            $i }).';';
591
        }
592
        $hclickable_text = null;
593
        // Encrypt clickable text if @ is present
594
        if (strpos($clickable_text, '@')) {
595
            for ($i = 0; $i < strlen($clickable_text); $i ++) {
596
                $hclickable_text .= '&#'.ord($clickable_text {
597
                $i }).';';
598
            }
599
        } else {
600
            $hclickable_text = @htmlspecialchars($clickable_text, ENT_QUOTES, api_get_system_encoding());
601
        }
602
        // Return encrypted mailto hyperlink
603
        return '<a href="'.$hmail.'"'.$style_class.' class="clickable_email_link">'.$hclickable_text.'</a>';
604
    }
605
606
    /**
607
     * Returns an mailto icon hyperlink
608
     *
609
     * @param string  e-mail
610
     * @param string  icon source file from the icon lib
611
     * @param integer  icon size from icon lib
612
     * @param string  optional, class from stylesheet
613
     * @return string encrypted mailto hyperlink
614
     */
615
    public static function icon_mailto_link($email, $icon_file = "mail.png", $icon_size = 22, $style_class = '')
616
    {
617
        // "mailto:" already present?
618
        if (substr($email, 0, 7) != 'mailto:') {
619
            $email = 'mailto:'.$email;
620
        }
621
        // Class (stylesheet) defined?
622
        if ($style_class != '') {
623
            $style_class = ' class="'.$style_class.'"';
624
        }
625
        // Encrypt email
626
        $hmail = '';
627 View Code Duplication
        for ($i = 0; $i < strlen($email); $i ++) {
628
            $hmail .= '&#'.ord($email {
629
            $i }).';';
630
        }
631
        // icon html code
632
        $icon_html_source = self::return_icon($icon_file, $hmail, '', $icon_size);
633
        // Return encrypted mailto hyperlink
634
635
        return '<a href="'.$hmail.'"'.$style_class.' class="clickable_email_link">'.$icon_html_source.'</a>';
636
    }
637
638
    /**
639
     * Prints an <option>-list with all letters (A-Z).
640
     * @param char $selected_letter The letter that should be selected
641
     * @todo This is English language specific implementation.
642
     * It should be adapted for the other languages.
643
     */
644 View Code Duplication
    public static function get_alphabet_options($selected_letter = '')
645
    {
646
        $result = '';
647
        for ($i = 65; $i <= 90; $i ++) {
648
            $letter = chr($i);
649
            $result .= '<option value="'.$letter.'"';
650
            if ($selected_letter == $letter) {
651
                $result .= ' selected="selected"';
652
            }
653
            $result .= '>'.$letter.'</option>';
654
        }
655
        return $result;
656
    }
657
658
    /**
659
     * Get the options withing a select box within the given values
660
     * @param int   Min value
661
     * @param int   Max value
662
     * @param int   Default value
663
     * @return string HTML select options
664
     */
665 View Code Duplication
    public static function get_numeric_options($min, $max, $selected_num = 0)
666
    {
667
        $result = '';
668
        for ($i = $min; $i <= $max; $i ++) {
669
            $result .= '<option value="'.$i.'"';
670
            if (is_int($selected_num))
671
                if ($selected_num == $i) {
672
                    $result .= ' selected="selected"';
673
                }
674
            $result .= '>'.$i.'</option>';
675
        }
676
        return $result;
677
    }
678
679
    /**
680
     * This public function displays an icon
681
     * @param string   The filename of the file (in the main/img/ folder
682
     * @param string   The alt text (probably a language variable)
683
     * @param array    additional attributes (for instance height, width, onclick, ...)
684
     * @param integer  The wanted width of the icon (to be looked for in the corresponding img/icons/ folder)
685
     * @return void
686
    */
687
    public static function display_icon(
688
        $image,
689
        $alt_text = '',
690
        $additional_attributes = array(),
691
        $size = null
692
    ) {
693
        echo self::return_icon($image, $alt_text, $additional_attributes, $size);
694
    }
695
696
    /**
697
     * Gets the path of an icon
698
     *
699
     * @param string $icon
700
     * @param int $size
701
     *
702
     * @return string
703
     */
704
    public static function returnIconPath($icon, $size = ICON_SIZE_SMALL)
705
    {
706
        return Display::return_icon($icon, null, null, $size, null, true, false);
707
    }
708
709
    /**
710
     * This public function returns the htmlcode for an icon
711
     *
712
     * @param string   The filename of the file (in the main/img/ folder
713
     * @param string   The alt text (probably a language variable)
714
     * @param array    Additional attributes (for instance height, width, onclick, ...)
715
     * @param integer  The wanted width of the icon (to be looked for in the corresponding img/icons/ folder)
716
     * @return string  An HTML string of the right <img> tag
717
     *
718
     * @author Patrick Cool <[email protected]>, Ghent University 2006
719
     * @author Julio Montoya 2010 Function improved, adding image constants
720
     * @author Yannick Warnier 2011 Added size handler
721
     * @version Feb 2011
722
    */
723
    public static function return_icon(
724
        $image,
725
        $alt_text = '',
726
        $additional_attributes = array(),
727
        $size = ICON_SIZE_SMALL,
728
        $show_text = true,
729
        $return_only_path = false,
730
        $loadThemeIcon = true
731
    ) {
732
        $image = trim($image);
733
        $size_extra = '';
734
        if (isset($size)) {
735
        $size_extra = $size . '/';
736
        }  
737
738
        $icon = 'bundles/chamilocore/img/icons/'.$size_extra.$image;
739
        $icon = Container::getAsset()->getUrl($icon);
740
741
        if ($return_only_path) {
742
            return $icon;
743
        }
744
745
        $img = self::img($icon, $alt_text, $additional_attributes);
746
        if (SHOW_TEXT_NEAR_ICONS == true && !empty($alt_text)) {
747
            if ($show_text) {
748
                $img = "$img $alt_text";
749
            }
750
        }
751
752
        return $img;
753
    }
754
755
    /**
756
     * Returns the htmlcode for an image
757
     *
758
     * @param string $image_path the filename of the file (in the main/img/ folder
759
     * @param string $alt_text the alt text (probably a language variable)
760
     * @param array  $additional_attributes (for instance height, width, onclick, ...)
761
     * @param boolean $filterPath Optional. Whether filter the image path. Default is true
762
     * @author Julio Montoya 2010
763
     */
764
    public static function img($image_path, $alt_text = '', $additional_attributes = array(), $filterPath = true)
765
    {
766
        // Sanitizing the parameter $image_path
767
        if ($filterPath) {
768
            $image_path = Security::filter_img_path($image_path);
769
        }
770
771
        // alt text = the image name if there is none provided (for XHTML compliance)
772
        if ($alt_text == '') {
773
            $alt_text = basename($image_path);
774
        }
775
776
        $additional_attributes['src'] = $image_path;
777
778
        if (empty($additional_attributes['alt'])) {
779
            $additional_attributes['alt'] = $alt_text;
780
        }
781
        if (empty($additional_attributes['title'])) {
782
            $additional_attributes['title'] = $alt_text;
783
        }
784
785
        return self::tag('img', '', $additional_attributes);
786
    }
787
788
    /**
789
     * Returns the htmlcode for a tag (h3, h1, div, a, button), etc
790
     *
791
     * @param string $tag the tag name
792
     * @param string $content the tag's content
793
     * @param array $additional_attributes (for instance height, width, onclick, ...)
794
     * @author Julio Montoya 2010
795
     */
796
    public static function tag($tag, $content, $additional_attributes = array())
797
    {
798
        $attribute_list = '';
799
        // Managing the additional attributes
800
        if (!empty($additional_attributes) && is_array($additional_attributes)) {
801
            $attribute_list = '';
802
            foreach ($additional_attributes as $key => & $value) {
803
                $attribute_list .= $key.'="'.$value.'" ';
804
            }
805
        }
806
        //some tags don't have this </XXX>
807
        if (in_array($tag, array('img','input','br'))) {
808
            $return_value = '<'.$tag.' '.$attribute_list.' />';
809
        } else {
810
            $return_value = '<'.$tag.' '.$attribute_list.' >'.$content.'</'.$tag.'>';
811
        }
812
        return $return_value;
813
    }
814
815
    /**
816
     * Creates a URL anchor
817
     * @param string $name
818
     * @param string $url
819
     * @param array $attributes
820
     *
821
     * @return string
822
     */
823
    public static function url($name, $url, $attributes = array())
824
    {
825
        if (!empty($url)) {
826
            $url = preg_replace('#&amp;#', '&', $url);
827
            $url = htmlspecialchars($url, ENT_QUOTES, 'UTF-8');
828
            $attributes['href'] = $url;
829
        }
830
        return self::tag('a', $name, $attributes);
831
    }
832
833
    /**
834
     * Creates a div tag
835
     *
836
     * @param string $content
837
     * @param array $attributes
838
     * @return string
839
     */
840
    public static function div($content, $attributes = array())
841
    {
842
        return self::tag('div', $content, $attributes);
843
    }
844
845
    /**
846
     * Creates a span tag
847
     */
848
    public static function span($content, $attributes = array())
849
    {
850
        return self::tag('span', $content, $attributes);
851
    }
852
853
    /**
854
     * Displays an HTML input tag
855
     *
856
     */
857
    public static function input($type, $name, $value, $attributes = array())
858
    {
859
         if (isset($type)) {
860
             $attributes['type']= $type;
861
         }
862
         if (isset($name)) {
863
             $attributes['name']= $name;
864
         }
865
         if (isset($value)) {
866
             $attributes['value']= $value;
867
        }
868
        return self::tag('input', '', $attributes);
869
    }
870
871
    /**
872
     * @param $name
873
     * @param $value
874
     * @param array $attributes
875
     * @return string
876
     */
877
    public static function button($name, $value, $attributes = array())
878
    {
879
    	if (!empty($name)) {
880
            $attributes['name'] = $name;
881
    	}
882
    	return self::tag('button', $value, $attributes);
883
    }
884
885
    /**
886
     * Displays an HTML select tag
887
     *
888
     */
889
    public static function select(
890
        $name,
891
        $values,
892
        $default = -1,
893
        $extra_attributes = array(),
894
        $show_blank_item = true,
895
        $blank_item_text = null
896
    ) {
897
        $html = '';
898
        $extra = '';
899
        $default_id = 'id="' . $name . '" ';
900
        foreach ($extra_attributes as $key => $parameter) {
901
            if ($key == 'id') {
902
                $default_id = '';
903
            }
904
            $extra .= $key . '="' . $parameter . '" ';
905
        }
906
        $html .= '<select name="' . $name . '" ' . $default_id . ' ' . $extra . '>';
907
908
        if ($show_blank_item) {
909
            if (empty($blank_item_text)) {
910
                $blank_item_text = get_lang('Select');
911
            } else {
912
                $blank_item_text = Security::remove_XSS($blank_item_text);
913
            }
914
            $html .= self::tag('option', '-- ' . $blank_item_text . ' --', array('value' => '-1'));
915
        }
916
        if ($values) {
917
            foreach ($values as $key => $value) {
918
                if (is_array($value) && isset($value['name'])) {
919
                    $value = $value['name'];
920
                }
921
                $html .= '<option value="' . $key . '"';
922
923
                if (is_array($default)) {
924
                    foreach ($default as $item) {
925
                        if ($item == $key) {
926
                            $html .= ' selected="selected"';
927
                            break;
928
                        }
929
                    }
930
                } else {
931
                    if ($default == $key) {
932
                        $html .= ' selected="selected"';
933
                    }
934
                }
935
936
                $html .= '>' . $value . '</option>';
937
            }
938
        }
939
        $html .= '</select>';
940
        return $html;
941
    }
942
943
    /**
944
     * Creates a tab menu
945
     * Requirements: declare the jquery, jquery-ui libraries + the jquery-ui.css
946
     * in the $htmlHeadXtra variable before the display_header
947
     * Add this script
948
     * @example
949
             * <script>
950
                    $(function() {
951
                        $( "#tabs" ).tabs();
952
                    });
953
                </script>
954
     * @param   array   $headers list of the tab titles
955
     * @param   array   $items
956
     * @param   string  $id id of the container of the tab in the example "tabs"
957
     * @param   array   $attributes for the ul
958
     * @param array $ul_attributes
959
     *
960
     * @return string
961
     */
962
    public static function tabs($headers, $items, $id = 'tabs', $attributes = array(), $ul_attributes = array())
963
    {
964
        if (empty($headers) || count($headers) == 0 ) {
965
            return '';
966
        }
967
968
        $lis = '';
969
        $i = 1;
970
        foreach ($headers as $item) {
971
            $active = '';
972
            if ($i == 1) {
973
                $active = ' active';
974
            }
975
            $item = self::tag('a', $item, array('href'=>'#'.$id.'-'.$i, 'role'=> 'tab', 'data-toggle' => 'tab', 'id' => $id . $i));
976
            $ul_attributes['role'] = 'presentation';
977
            $ul_attributes['class'] = $active;
978
            $lis .= self::tag('li', $item, $ul_attributes);
979
            $i++;
980
        }
981
        $ul = self::tag('ul', $lis, ['class' => 'nav nav-tabs', 'role'=> 'tablist', 'id' => 'ul_'.$id]);
982
983
        $i = 1;
984
        $divs = '';
985
        foreach ($items as $content) {
986
            $active = '';
987
            if ($i == 1) {
988
                $active = ' active';
989
            }
990
            $divs .= self::tag(
991
                'div',
992
                $content,
993
                array('id' => $id.'-'.$i, 'class' => 'tab-pane '.$active, 'role' => 'tabpanel')
994
            );
995
            $i++;
996
        }
997
998
        $attributes['id'] = $id;
999
        $attributes['role'] = 'tabpanel';
1000
        $attributes['class'] = 'tab-wrapper';
1001
1002
        $main_div = self::tag('div', $ul.self::tag('div', $divs, ['class' => 'tab-content']), $attributes);
1003
1004
        return $main_div ;
1005
    }
1006
1007
    /**
1008
     * @param $headers
1009
     * @param null $selected
1010
     *
1011
     * @return string
1012
     */
1013
    public static function tabsOnlyLink($headers, $selected = null)
1014
    {
1015
         $id = uniqid();
1016
         $i = 1;
1017
         $lis = null;
1018
         foreach ($headers as $item) {
1019
            $class = null;
1020
            if ($i == $selected) {
1021
                $class = 'active';
1022
            }
1023
             $item = self::tag(
1024
                 'a',
1025
                 $item['content'],
1026
                 array('id' => $id.'-'.$i, 'href' => $item['url'])
1027
             );
1028
             $lis .= self::tag('li', $item, array('class' => $class));
1029
            $i++;
1030
        }
1031
        return self::tag('ul', $lis, array('class' => 'nav nav-tabs tabs-margin'));
1032
    }
1033
1034
    /**
1035
     * In order to display a grid using jqgrid you have to:
1036
     * @example
1037
     * After your Display::display_header function you have to add the nex javascript code:     *
1038
     * <script>
1039
     *   echo Display::grid_js('my_grid_name', $url,$columns, $column_model, $extra_params,array());
1040
     *   // for more information of this function check the grid_js() function
1041
     * </script>
1042
     * //Then you have to call the grid_html
1043
     * echo Display::grid_html('my_grid_name');
1044
     * As you can see both function use the same "my_grid_name" this is very important otherwise nothing will work
1045
     *
1046
     * @param   string  the div id, this value must be the same with the first parameter of Display::grid_js()
1047
     * @return  string  html
1048
     *
1049
     */
1050
    public static function grid_html($div_id)
1051
    {
1052
        $table = self::tag('table','', array('id' => $div_id));
1053
        $table .= self::tag('div','', array('id' => $div_id.'_pager'));
1054
        return $table;
1055
    }
1056
1057
    /**
1058
     * @param string $label
1059
     * @param string $form_item
1060
     * @return string
1061
     */
1062
    public static function form_row($label, $form_item)
1063
    {
1064
        $label = self::span($label, array('class' =>'control-label'));
1065
        $form_item = self::div($form_item, array('class' =>'controls'));
1066
        return self::div($label.$form_item, array('class'=>'control-group'));
1067
    }
1068
1069
    /**
1070
     * This is a wrapper to use the jqgrid in Chamilo.
1071
     * For the other jqgrid options visit http://www.trirand.com/jqgridwiki/doku.php?id=wiki:options
1072
     * This function need to be in the ready jquery function
1073
     * example --> $(function() { <?php echo Display::grid_js('grid' ...); ?> }
1074
     * In order to work this function needs the Display::grid_html function with the same div id
1075
     *
1076
     * @param   string  $div_id div id
1077
     * @param   string  $url url where the jqgrid will ask for data (if datatype = json)
1078
     * @param   array   $column_names Visible columns (you should use get_lang). An array in which we place the names of the columns.
1079
     * 					This is the text that appears in the head of the grid (Header layer).
1080
     * 					Example: colname   {name:'date',     index:'date',   width:120, align:'right'},
1081
     * @param   array   $column_model the column model :  Array which describes the parameters of the columns.This is the most important part of the grid.
1082
     * 					For a full description of all valid values see colModel API. See the url above.
1083
     * @param   array   $extra_params extra parameters
1084
     * @param   array   $data data that will be loaded
1085
     * @param	string	$formatter A string that will be appended to the JSON returned
1086
     * @param	bool	$fixed_width not implemented yet
1087
     * @return  string  the js code
1088
     *
1089
     */
1090
    public static function grid_js(
1091
        $div_id,
1092
        $url,
1093
        $column_names,
1094
        $column_model,
1095
        $extra_params,
1096
        $data = array(),
1097
        $formatter = '',
1098
        $fixed_width = false
1099
    ) {
1100
        $obj = new stdClass();
1101
        $obj->first = 'first';
1102
1103
        if (!empty($url)) {
1104
            $obj->url = $url;
1105
        }
1106
1107
        //This line should only be used/modified in case of having characters
1108
        // encoding problems - see #6159
1109
        //$column_names = array_map("utf8_encode", $column_names);
1110
1111
        $obj->colNames      = $column_names;
1112
        $obj->colModel      = $column_model;
1113
        $obj->pager         = '#'.$div_id.'_pager';
1114
        $obj->datatype  = 'json';
1115
        $obj->viewrecords = 'true';
1116
1117
        $all_value = 10000000;
1118
1119
        // Default row quantity
1120
        if (!isset($extra_params['rowList'])) {
1121
            $extra_params['rowList'] = array(20, 50, 100, 500, 1000, $all_value);
1122
        }
1123
1124
        $json = '';
1125
        if (!empty($extra_params['datatype'])) {
1126
            $obj->datatype = $extra_params['datatype'];
1127
        }
1128
1129
        // Row even odd style.
1130
        $obj->altRows = true;
1131
        if (!empty($extra_params['altRows'])) {
1132
            $obj->altRows = $extra_params['altRows'];
1133
        }
1134
1135
        if (!empty($extra_params['sortname'])) {
1136
            $obj->sortname = $extra_params['sortname'];
1137
        }
1138
1139
        if (!empty($extra_params['sortorder'])) {
1140
            $obj->sortorder = $extra_params['sortorder'];
1141
        }
1142
1143
        if (!empty($extra_params['rowList'])) {
1144
            $obj->rowList = $extra_params['rowList'];
1145
        }
1146
        //Sets how many records we want to view in the grid
1147
        $obj->rowNum = 20;
1148
        if (!empty($extra_params['rowNum'])) {
1149
            $obj->rowNum = $extra_params['rowNum'];
1150
        }
1151
1152
        if (!empty($extra_params['viewrecords'])) {
1153
            $obj->viewrecords = $extra_params['viewrecords'];
1154
        }
1155
1156
        $beforeSelectRow = null;
1157
        if (isset($extra_params['beforeSelectRow'])) {
1158
            $beforeSelectRow = "beforeSelectRow: ".$extra_params['beforeSelectRow'].", ";
1159
            unset($extra_params['beforeSelectRow']);
1160
        }
1161
1162
        // Adding extra params
1163
        if (!empty($extra_params)) {
1164
            foreach ($extra_params as $key => $element) {
1165
                // the groupHeaders key gets a special treatment
1166
                if ($key != 'groupHeaders') {
1167
                    $obj->$key = $element;
1168
                }
1169
            }
1170
        }
1171
1172
        // Adding static data.
1173
        if (!empty($data)) {
1174
            $data_var = $div_id.'_data';
1175
            $json.=' var '.$data_var.' = '.json_encode($data).';';
1176
            $obj->data = $data_var;
1177
            $obj->datatype = 'local';
1178
            $json.="\n";
1179
        }
1180
1181
        $obj->end = 'end';
1182
1183
        $json_encode = json_encode($obj);
1184
1185
        if (!empty($data)) {
1186
            //Converts the "data":"js_variable" to "data":js_variable,
1187
            // otherwise it will not work
1188
            $json_encode = str_replace('"data":"'.$data_var.'"', '"data":'.$data_var.'', $json_encode);
1189
        }
1190
1191
        // Fixing true/false js values that doesn't need the ""
1192
        $json_encode = str_replace(':"true"',':true',$json_encode);
1193
        // wrap_cell is not a valid jqgrid attributes is a hack to wrap a text
1194
        $json_encode = str_replace('"wrap_cell":true', 'cellattr : function(rowId, value, rowObject, colModel, arrData) { return \'class = "jqgrid_whitespace"\'; }', $json_encode);
1195
        $json_encode = str_replace(':"false"',':false',$json_encode);
1196
        $json_encode = str_replace('"formatter":"action_formatter"', 'formatter:action_formatter', $json_encode);
1197
        $json_encode = str_replace(array('{"first":"first",','"end":"end"}'), '', $json_encode);
1198
1199
        // Creating the jqgrid element.
1200
        $json .= '$("#'.$div_id.'").jqGrid({';
1201
        //$json .= $beforeSelectRow;
1202
1203
        $json .= $json_encode;
1204
1205
        $json .= '});';
1206
1207
        // Grouping headers option
1208
        if (isset($extra_params['groupHeaders'])) {
1209
            $groups = '';
1210
            foreach ($extra_params['groupHeaders'] as $group) {
1211
                //{ "startColumnName" : "courses", "numberOfColumns" : 1, "titleText" : "Order Info" },
1212
                $groups .= '{ "startColumnName" : "' . $group['startColumnName'] . '", "numberOfColumns" : ' . $group['numberOfColumns'] . ', "titleText" : "' . $group['titleText']  . '" },';
1213
1214
            }
1215
            $json .= '$("#'.$div_id.'").jqGrid("setGroupHeaders", {
1216
                "useColSpanStyle" : false,
1217
                "groupHeaders"    : [
1218
                    ' . $groups . '
1219
                ]
1220
            });';
1221
        }
1222
1223
        $all_text = addslashes(get_lang('All'));
1224
        $json .= '$("'.$obj->pager.' option[value='.$all_value.']").text("'.$all_text.'");';
1225
        $json.= "\n";
1226
        // Adding edit/delete icons.
1227
        $json.= $formatter;
1228
1229
        return $json;
1230
    }
1231
1232
    /**
1233
     * @param array $headers
1234
     * @param array $rows
1235
     * @param array $attributes
1236
     * @return string
1237
     */
1238
    public static function table($headers, $rows, $attributes = array())
1239
    {
1240
    	if (empty($attributes)) {
1241
    		$attributes['class'] = 'data_table';
1242
        }
1243
        $table = new HTML_Table($attributes);
1244
        $row = 0;
1245
        $column = 0;
1246
1247
        // Course headers
1248
        if (!empty($headers)) {
1249
	        foreach ($headers as $item) {
1250
	            $table->setHeaderContents($row, $column, $item);
1251
	            $column++;
1252
	        }
1253
	        $row = 1;
1254
	        $column = 0;
1255
        }
1256
1257
        if (!empty($rows)) {
1258
	        foreach($rows as $content) {
1259
	            $table->setCellContents($row, $column, $content);
1260
                $row++;
1261
            }
1262
        }
1263
        return $table->toHtml();
1264
    }
1265
1266
    /**
1267
     * Returns the "what's new" icon notifications
1268
     *
1269
     * The general logic of this function is to track the last time the user
1270
     * entered the course and compare to what has changed inside this course
1271
     * since then, based on the item_property table inside this course. Note that,
1272
     * if the user never entered the course before, he will not see notification
1273
     * icons. This function takes session ID into account (if any) and only shows
1274
     * the corresponding notifications.
1275
     * @param array     Course information array, containing at least elements 'db' and 'k'
1276
     * @return string   The HTML link to be shown next to the course
1277
     */
1278
    public static function show_notification($course_info)
1279
    {
1280
        if (empty($course_info)) {
1281
            return '';
1282
        }
1283
1284
        $t_track_e_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS);
1285
        $course_tool_table = Database::get_course_table(TABLE_TOOL_LIST);
1286
        $tool_edit_table = Database::get_course_table(TABLE_ITEM_PROPERTY);
1287
        $course_code = Database::escape_string($course_info['code']);
1288
1289
        $user_id = api_get_user_id();
1290
        $course_id = intval($course_info['real_id']);
1291
        $sessionId = intval($course_info['id_session']);
1292
1293
        // Get the user's last access dates to all tools of this course
1294
        $sql = "SELECT *
1295
                FROM $t_track_e_access
1296
                WHERE
1297
                    c_id = $course_id AND
1298
                    access_user_id = '$user_id' AND
1299
                    access_session_id ='".$sessionId."'";
1300
        $resLastTrackInCourse = Database::query($sql);
1301
1302
        $oldestTrackDate = $oldestTrackDateOrig = '3000-01-01 00:00:00';
1303
        while ($lastTrackInCourse = Database::fetch_array($resLastTrackInCourse)) {
1304
            $lastTrackInCourseDate[$lastTrackInCourse['access_tool']] = $lastTrackInCourse['access_date'];
1305
            if ($oldestTrackDate > $lastTrackInCourse['access_date']) {
1306
                $oldestTrackDate = $lastTrackInCourse['access_date'];
1307
            }
1308
        }
1309
1310
        if ($oldestTrackDate == $oldestTrackDateOrig) {
1311
            //if there was no connexion to the course ever, then take the
1312
            // course creation date as a reference
1313
            $oldestTrackDate = $course_info['creation_date'];
1314
        }
1315
1316
        $sessionCondition = api_get_session_condition(
1317
            $sessionId,
1318
            true,
1319
            false,
1320
            'tet.session_id'
1321
        );
1322
1323
        // Get the last edits of all tools of this course.
1324
        $sql = "SELECT
1325
                    tet.*,
1326
                    tet.lastedit_date last_date,
1327
                    tet.tool tool,
1328
                    tet.ref ref,
1329
                    tet.lastedit_type type,
1330
                    tet.to_group_id group_id,
1331
                    ctt.image image,
1332
                    ctt.link link
1333
                FROM $tool_edit_table tet
1334
                INNER JOIN $course_tool_table ctt
1335
                ON tet.c_id = ctt.c_id
1336
                WHERE
1337
                    tet.c_id = $course_id AND
1338
                    tet.lastedit_date > '$oldestTrackDate' ".
1339
                    // Special hack for work tool, which is called student_publication in c_tool and work in c_item_property :-/ BT#7104
1340
                    " AND (ctt.name = tet.tool OR (ctt.name = 'student_publication' AND tet.tool = 'work'))
1341
                    AND ctt.visibility = '1'
1342
                    AND tet.lastedit_user_id != $user_id $sessionCondition
1343
                 ORDER BY tet.lastedit_date";
1344
1345
        $res = Database::query($sql);
1346
        // Get the group_id's with user membership.
1347
        $group_ids = GroupManager :: get_group_ids($course_info['real_id'], $user_id);
1348
        $group_ids[] = 0; //add group 'everyone'
1349
        $notifications = array();
1350
        // Filter all last edits of all tools of the course
1351
        while ($res && ($item_property = Database::fetch_array($res, 'ASSOC'))) {
1352
1353
            // First thing to check is if the user never entered the tool
1354
            // or if his last visit was earlier than the last modification.
1355
            if ((!isset($lastTrackInCourseDate[$item_property['tool']])
1356
                 || $lastTrackInCourseDate[$item_property['tool']] < $item_property['lastedit_date'])
1357
                // Drop the tool elements that are part of a group that the
1358
                // user is not part of.
1359
                && ((in_array($item_property['to_group_id'], $group_ids)
1360
                // Drop the dropbox, notebook and chat tools (we don't care)
1361
                && (
1362
                        //$item_property['tool'] != TOOL_DROPBOX &&
1363
                        $item_property['tool'] != TOOL_NOTEBOOK &&
1364
                        $item_property['tool'] != TOOL_CHAT)
1365
                   )
1366
                )
1367
                // Take only what's visible or "invisible but where the user is a teacher" or where the visibility is unset.
1368
                && ($item_property['visibility'] == '1'
1369
                    || ($course_info['status'] == '1' && $item_property['visibility'] == '0')
1370
                    || !isset($item_property['visibility']))
1371
            ) {
1372
                // Also drop announcements and events that are not for the user or his group.
1373
                if ((
1374
                        $item_property['tool'] == TOOL_ANNOUNCEMENT ||
1375
                        $item_property['tool'] == TOOL_CALENDAR_EVENT
1376
                    ) &&
1377
                    (
1378
                        ($item_property['to_user_id'] != $user_id) &&
1379
                        (!isset($item_property['to_group_id']) || !in_array($item_property['to_group_id'], $group_ids)))
1380
                ) {
1381
                   continue;
1382
                }
1383
1384
                // If it's a survey, make sure the user's invited. Otherwise drop it.
1385
                if ($item_property['tool'] == TOOL_SURVEY) {
1386
                    $survey_info = SurveyManager::get_survey($item_property['ref'], 0, $course_code);
1387
                    if (!empty($survey_info)) {
1388
                        $invited_users = SurveyUtil::get_invited_users(
1389
                            $survey_info['code'],
1390
                            $course_code
1391
                        );
1392
                        if (!in_array($user_id, $invited_users['course_users'])) {
1393
                            continue;
1394
                        }
1395
                    }
1396
                }
1397
1398
                // If it's a learning path, ensure it is currently visible to the user
1399
                if ($item_property['tool'] == TOOL_LEARNPATH) {
1400
                    if (!learnpath::is_lp_visible_for_student($item_property['ref'], $user_id, $course_code)) {
1401
                        continue;
1402
                    }
1403
                }
1404
1405
                if ($item_property['tool'] == TOOL_DROPBOX) {
1406
                    $item_property['link'] = 'dropbox/dropbox_download.php?id='.$item_property['ref'];
1407
                }
1408
1409
                if ($item_property['tool'] == 'work' &&
1410
                    $item_property['type'] == 'DirectoryCreated'
1411
                ) {
1412
                    $item_property['lastedit_type'] = 'WorkAdded';
1413
                }
1414
                $notifications[$item_property['tool']] = $item_property;
1415
            }
1416
        }
1417
1418
        // Show all tool icons where there is something new.
1419
        $return = '&nbsp;';
1420
        foreach($notifications as $notification) {
1421
            $lastDate = date('d/m/Y H:i', convert_sql_date($notification['lastedit_date']));
1422
            $type = $notification['lastedit_type'];
1423
            $label = get_lang('TitleNotification').": ".get_lang($type)." ($lastDate)";
1424
1425
            if (strpos($notification['link'], '?') === false) {
1426
                $notification['link'] = $notification['link'].'?notification=1';
1427
            } else {
1428
                $notification['link'] = $notification['link'].'&notification=1';
1429
            }
1430
            $imagen = substr($notification['image'], 0, -4).'.png';
1431
            $return .= Display::url(
1432
                Display::return_icon($imagen, $label),
1433
                api_get_path(WEB_CODE_PATH).
1434
                $notification['link'].'&cidReq='.$course_code.
1435
                '&ref='.$notification['ref'].
1436
                '&gidReq='.$notification['to_group_id'].
1437
                '&id_session='.$sessionId
1438
            ).'&nbsp;';
1439
        }
1440
1441
        return $return;
1442
    }
1443
1444
    /**
1445
     * Get the session box details as an array
1446
     * @param int       Session ID
1447
     * @return array    Empty array or session array
1448
     * ['title'=>'...','category'=>'','dates'=>'...','coach'=>'...','active'=>true/false,'session_category_id'=>int]
1449
     */
1450
    public static function get_session_title_box($session_id)
1451
    {
1452
        global $nosession;
1453
1454
        if (!$nosession) {
1455
            global $now, $date_start, $date_end;
1456
        }
1457
        $output = array();
1458
        $active = false;
1459
        if (!$nosession) {
1460
            $main_user_table = Database :: get_main_table(TABLE_MAIN_USER);
1461
            $tbl_session = Database :: get_main_table(TABLE_MAIN_SESSION);
1462
            // Request for the name of the general coach
1463
            $sql ='SELECT tu.lastname, tu.firstname, ts.*
1464
                    FROM '.$tbl_session.' ts
1465
                    LEFT JOIN '.$main_user_table .' tu
1466
                    ON ts.id_coach = tu.user_id
1467
                    WHERE ts.id = '.intval($session_id);
1468
            $rs = Database::query($sql);
1469
            $session_info = Database::store_result($rs, 'ASSOC');
1470
            $session_info = $session_info[0];
1471
1472
            $session = array();
1473
            $session['category_id'] = $session_info['session_category_id'];
1474
            $session['title'] = $session_info['name'];
1475
            $session['id_coach'] = $session_info['id_coach'];
1476
            $session['coach'] = '';
1477
            $session['dates'] =  '';
1478
1479
            if (($session_info['access_end_date'] == '0000-00-00 00:00:00' && $session_info['access_start_date'] == '0000-00-00 00:00:00') ||
1480
                ($session_info['access_end_date'] == '0000-00-00 00:00:00' && $session_info['access_start_date'] == '0000-00-00 00:00:00') ||
1481
                (empty($session_info['access_end_date']) && empty($session_info['access_start_date']))
1482
            ) {
1483 View Code Duplication
                if (api_get_setting('show_session_coach') === 'true') {
1484
                    $session['coach'] = get_lang('GeneralCoach').': '.api_get_person_name($session_info['firstname'], $session_info['lastname']);
1485
                }
1486
1487
                if (isset($session_info['duration']) && !empty($session_info['duration'])) {
1488
                    $userDurationData = SessionManager::getUserSession(
1489
                        api_get_user_id(),
1490
                        $session_id
1491
                    );
1492
1493
                    $userDuration = isset($userDurationData['duration']) ? (int) $userDurationData['duration'] : 0;
1494
                    $totalDuration = $session_info['duration'] + $userDuration;
1495
1496
                    $daysLeft = SessionManager::getDayLeftInSession(
1497
                        $session_id,
1498
                        api_get_user_id(),
1499
                        $totalDuration
1500
                    );
1501
                    $session['duration'] = sprintf(get_lang('SessionDurationXDaysLeft'), $daysLeft);
1502
                }
1503
                $active = true;
1504
            } else {
1505
                /*$start = $stop = false;
1506
                $start_buffer = $stop_buffer = '';
1507
                if ($session_info['access_start_date'] === '0000-00-00 00:00:00' || empty($session_info['access_start_date'])) {
1508
                    $session_info['access_start_date'] = '';
1509
                } else {
1510
                    $start = true;
1511
                    $start_buffer = $session_info['access_start_date'];
1512
                    $session_info['access_start_date'] = $session_info['access_start_date'];
1513
                }
1514
                if ($session_info['access_end_date'] === '0000-00-00 00:00:00' || empty($session_info['access_end_date'])) {
1515
                    $session_info['access_end_date'] = '';
1516
                } else {
1517
                    $stop = true;
1518
                    $stop_buffer = $session_info['access_end_date'];
1519
                    $session_info['access_end_date'] = $session_info['access_end_date'];
1520
                }
1521
                if ($start && $stop) {
1522
                    $session['dates'] = sprintf(
1523
                        get_lang('FromDateXToDateY'),
1524
                        api_format_date($start_buffer),
1525
                        api_format_date($stop_buffer)
1526
                    );
1527
                } else {
1528
                    $start_buffer = $stop_buffer = null;
1529
                    if (!empty($session_info['access_start_date'])) {
1530
                        $start_buffer = sprintf(
1531
                            get_lang('FromDateX'),
1532
                            api_format_date(api_get_local_time($session_info['access_start_date']))
1533
                        );
1534
                    }
1535
1536
                    if (!empty($session_info['access_end_date'])) {
1537
                        $stop_buffer = sprintf(
1538
                            get_lang('UntilDateX'),
1539
                            api_format_date(api_get_local_time($session_info['access_end_date']))
1540
                        );
1541
                    }*/
1542
1543
                $dates = SessionManager::parseSessionDates($session_info, true);
1544
1545
                //$session['dates'] = $start_buffer . ' ' . $stop_buffer.'- julio '.$dates['access'];
1546
                $session['dates'] = $dates['access'];
1547
1548
1549
                if (api_get_setting('show_session_coach') === 'true' ) {
1550
                    $session['coach'] = api_get_person_name(
1551
                        $session_info['firstname'],
1552
                        $session_info['lastname']
1553
                    );
1554
                }
1555
                $active = $date_start <= $now && $date_end >= $now;
1556
            }
1557
            $session['active'] = $active;
1558
            $session['session_category_id'] = $session_info['session_category_id'];
1559
            $session['visibility'] = $session_info['visibility'];
1560
            $session['num_users'] = $session_info['nbr_users'];
1561
            $session['num_courses'] = $session_info['nbr_courses'];
1562
            $session['description'] = $session_info['description'];
1563
            $session['show_description'] = $session_info['show_description'];
1564
1565
            $entityManager = Database::getManager();
1566
            $fieldValuesRepo = $entityManager->getRepository('ChamiloCoreBundle:ExtraFieldValues');
1567
            $extraFieldValues = $fieldValuesRepo->getVisibleValues(
1568
                ExtraField::SESSION_FIELD_TYPE,
1569
                $session_id
1570
            );
1571
1572
            $session['extra_fields'] = [];
1573
            foreach ($extraFieldValues as $value) {
1574
                $session['extra_fields'][] = [
1575
                    'field' => [
1576
                        'variable' => $value->getField()->getVariable(),
1577
                        'display_text' => $value->getField()->getDisplayText()
1578
                    ],
1579
                    'value' => $value->getValue()
1580
                ];
1581
            }
1582
1583
            $output = $session;
1584
        }
1585
        return $output;
1586
    }
1587
1588
    /**
1589
     * Return the five star HTML
1590
     *
1591
     * @param  string  id of the rating ul element
1592
     * @param  string  url that will be added (for jquery see hot_courses.tpl)
1593
	 * @param	string	point info array see function CourseManager::get_course_ranking()
1594
	 * @param	bool	add a div wrapper
1595
	 * @todo	use     templates
1596
     **/
1597
    public static function return_rating_system($id, $url, $point_info = array(), $add_div_wrapper = true)
1598
    {
1599
		$number_of_users_who_voted = isset($point_info['users_who_voted']) ? $point_info['users_who_voted'] : null;
1600
		$percentage = isset($point_info['point_average']) ? $point_info['point_average'] : 0;
1601
1602
		if (!empty($percentage)) {
1603
            $percentage = $percentage*125/100;
1604
        }
1605
		$accesses =  isset($point_info['accesses']) ? $point_info['accesses'] : 0;
1606
1607
		$star_label = sprintf(get_lang('XStarsOutOf5'), $point_info['point_average_star']);
1608
1609
        $html = '<ul id="'.$id.'" class="star-rating">
1610
					<li class="current-rating" style="width:'.$percentage.'px;"></li>
1611
					<li><a href="javascript:void(0);" data-link="'.$url.'&amp;star=1" title="'.$star_label.'" class="one-star">1</a></li>
1612
					<li><a href="javascript:void(0);" data-link="'.$url.'&amp;star=2" title="'.$star_label.'" class="two-stars">2</a></li>
1613
					<li><a href="javascript:void(0);" data-link="'.$url.'&amp;star=3" title="'.$star_label.'" class="three-stars">3</a></li>
1614
					<li><a href="javascript:void(0);" data-link="'.$url.'&amp;star=4" title="'.$star_label.'" class="four-stars">4</a></li>
1615
					<li><a href="javascript:void(0);" data-link="'.$url.'&amp;star=5" title="'.$star_label.'" class="five-stars">5</a></li>
1616
				</ul>';
1617
1618
		$labels = array();
1619
1620
		$labels[]= $number_of_users_who_voted == 1 ? $number_of_users_who_voted.' '.get_lang('Vote') : $number_of_users_who_voted.' '.get_lang('Votes');
1621
		$labels[]= $accesses == 1 ? $accesses.' '.get_lang('Visit') : $accesses.' '.get_lang('Visits');
1622
		/* if (!empty($number_of_users_who_voted)) {
1623
			$labels[]= get_lang('Average').' '.$point_info['point_average_star'].'/5';
1624
		} */
1625
1626
		$labels[]= $point_info['user_vote']  ? get_lang('YourVote').' ['.$point_info['user_vote'].']' : get_lang('YourVote'). ' [?] ';
1627
1628
		if (!$add_div_wrapper && api_is_anonymous()) {
1629
			$labels[]= Display::tag('span', get_lang('LoginToVote'), array('class' => 'error'));
1630
		}
1631
1632
        $html .= Display::div(implode(' | ', $labels) , array('id' =>  'vote_label_'.$id, 'class' => 'vote_label_info'));
1633
        $html .= ' '.Display::span(' ', array('id' =>  'vote_label2_'.$id));
1634
1635
        if ($add_div_wrapper) {
1636
			$html = Display::div($html, array('id' => 'rating_wrapper_'.$id));
1637
		}
1638
1639
        return $html;
1640
    }
1641
1642
    /**
1643
     * @param string $title
1644
     * @param string $second_title
1645
     * @param string $size
1646
     * @param bool $filter
1647
     * @return string
1648
     */
1649
    public static function page_header($title, $second_title = null, $size = 'h2', $filter = true)
1650
    {
1651
        if ($filter) {
1652
            $title = Security::remove_XSS($title);
1653
        }
1654
1655
        if (!empty($second_title)) {
1656
            if ($filter) {
1657
                $second_title = Security::remove_XSS($second_title);
1658
            }
1659
            $title .= "<small> $second_title<small>";
1660
        }
1661
        return '<div class="page-header"><'.$size.'>'.$title.'</'.$size.'></div>';
1662
    }
1663
1664
    public static function page_header_and_translate($title, $second_title = null)
1665
    {
1666
        $title = get_lang($title);
1667
        return self::page_header($title, $second_title);
1668
    }
1669
1670
     public static function page_subheader_and_translate($title, $second_title = null)
1671
     {
1672
        $title = get_lang($title);
1673
        return self::page_subheader($title, $second_title);
1674
    }
1675
1676
    public static function page_subheader($title, $second_title = null, $size = 'h3')
1677
    {
1678
        if (!empty($second_title)) {
1679
            $second_title = Security::remove_XSS($second_title);
1680
            $title .= "<small> $second_title<small>";
1681
        }
1682
        return '<'.$size.'>'.Security::remove_XSS($title).'</'.$size.'>';
1683
    }
1684
1685
    public static function page_subheader2($title, $second_title = null)
1686
    {
1687
        return self::page_header($title, $second_title, 'h4');
1688
    }
1689
1690
    public static function page_subheader3($title, $second_title = null)
1691
    {
1692
        return self::page_header($title, $second_title, 'h5');
1693
    }
1694
1695
    /**
1696
     * @param array $list
1697
     * @return null|string
1698
     */
1699
    public static function description($list)
1700
    {
1701
        $html = null;
1702
        if (!empty($list)) {
1703
            $html = '<dl class="dl-horizontal">';
1704
            foreach ($list as $item) {
1705
                $html .= '<dt>' . $item['title'] . '</dt>';
1706
                $html .= '<dd>' . $item['content'] . '</dd>';
1707
            }
1708
            $html .= '</dl>';
1709
        }
1710
        return $html;
1711
    }
1712
1713
    /**
1714
     * @param $percentage
1715
     * @param bool $show_percentage
1716
     * @param null $extra_info
1717
     * @return string
1718
     */
1719
    public static function bar_progress($percentage, $show_percentage = true, $extra_info = null)
1720
    {
1721
        $percentage = intval($percentage);
1722
        $div = '<div class="progress">
1723
                <div
1724
                    class="progress-bar progress-bar-striped"
1725
                    role="progressbar"
1726
                    aria-valuenow="'.$percentage.'"
1727
                    aria-valuemin="0"
1728
                    aria-valuemax="100"
1729
                    style="width: '.$percentage.'%;"
1730
                >';
1731
        if ($show_percentage) {
1732
            $div .= $percentage.'%';
1733
        } else {
1734
            if (!empty($extra_info)) {
1735
                $div .= $extra_info;
1736
            }
1737
        }
1738
        $div .= '</div>';
1739
1740
        return $div;
1741
    }
1742
1743
    /**
1744
     * @param string $count
1745
     * @param string $type
1746
     * @return null|string
1747
     */
1748
    public static function badge($count, $type ="warning")
1749
    {
1750
        $class = '';
1751
1752
        switch ($type) {
1753
            case 'success':
1754
                $class = 'badge-success';
1755
                break;
1756
            case 'warning':
1757
                $class = 'badge-warning';
1758
                break;
1759
            case 'important':
1760
                $class = 'badge-important';
1761
                break;
1762
            case 'info':
1763
                $class = 'badge-info';
1764
                break;
1765
            case 'inverse':
1766
                $class = 'badge-inverse';
1767
                break;
1768
        }
1769
1770
        if (!empty($count)) {
1771
            return ' <span class="badge '.$class.'">'.$count.'</span>';
1772
        }
1773
        return null;
1774
    }
1775
1776
    /**
1777
     * @param array $badge_list
1778
     * @return string
1779
     */
1780
    public static function badge_group($badge_list)
1781
    {
1782
        $html = '<div class="badge-group">';
1783
        foreach ($badge_list as $badge) {
1784
            $html .= $badge;
1785
        }
1786
        $html .= '</div>';
1787
        return $html;
1788
    }
1789
1790
    /**
1791
     * @param string $content
1792
     * @param string $type
1793
     * @return string
1794
     */
1795
    public static function label($content, $type = 'default')
1796
    {
1797
        switch ($type) {
1798
            case 'success':
1799
                $class = 'label-success';
1800
                break;
1801
            case 'warning':
1802
                $class = 'label-warning';
1803
                break;
1804
            case 'important':
1805
                //no break
1806
            case 'danger':
1807
                $class = 'label-danger';
1808
                break;
1809
            case 'info':
1810
                $class = 'label-info';
1811
                break;
1812
            case 'primary':
1813
                $class = 'label-primary';
1814
                break;
1815
            default:
1816
                $class = 'label-default';
1817
                break;
1818
        }
1819
1820
        $html = '';
1821
        if (!empty($content)) {
1822
            $html = '<span class="label '.$class.'">';
1823
            $html .= $content;
1824
            $html .='</span>';
1825
        }
1826
1827
        return $html;
1828
    }
1829
1830
    /**
1831
     * @param array $items
1832
     * @return null|string
1833
     */
1834
    public static function actions($items, $class = 'new_actions')
1835
    {
1836
        $html = null;
1837
        if (!empty($items)) {
1838
            $html = '<div class="'.$class.'"><ul class="nav nav-pills">';
1839
            foreach ($items as $value) {
1840
                $class = null;
1841
                if (isset($value['active']) && $value['active']) {
1842
                    $class = 'class ="active"';
1843
                }
1844
1845
                if (basename($_SERVER['REQUEST_URI']) == basename($value['url']) ) {
1846
                    $class = 'class ="active"';
1847
                }
1848
                $html .= "<li $class >";
1849
                $attributes = isset($value['url_attributes']) ? $value['url_attributes'] : array();
1850
                $html .= self::url($value['content'], $value['url'], $attributes);
1851
                $html .= '</li>';
1852
            }
1853
            $html .= '</ul></div>';
1854
            $html .= '<br />';
1855
        }
1856
1857
        return $html;
1858
    }
1859
1860
    /**
1861
     * Prints a tooltip
1862
     * @param string $text
1863
     * @param string $tip
1864
     *
1865
     * @return string
1866
     */
1867
    public static function tip($text, $tip)
1868
    {
1869
        if (empty($tip)) {
1870
            return $text;
1871
        }
1872
        return self::span($text, array('class' => 'boot-tooltip', 'title' => strip_tags($tip)));
1873
    }
1874
1875
    /**
1876
     * @param array $items
1877
     * @param string $type
1878
     * @param null $id
1879
     * @return null|string
1880
     */
1881
    public static function generate_accordion($items, $type = 'jquery', $id = null)
1882
    {
1883
        $html = null;
1884
        if (!empty($items)) {
1885
            if (empty($id)) {
1886
                $id = api_get_unique_id();
1887
            }
1888
            if ($type == 'jquery') {
1889
                $html = '<div class="accordion_jquery" id="'.$id.'">'; //using jquery
1890
            } else {
1891
                $html = '<div class="accordion" id="'.$id.'">'; //using bootstrap
1892
            }
1893
1894
            $count = 1;
1895
            foreach ($items as $item) {
1896
                $html .= '<div class="accordion-my-group">';
1897
                $html .= '<div class="accordion-heading">
1898
                            <a class="accordion-toggle" data-toggle="collapse" data-parent="#'.$id.'" href="#collapse'.$count.'">
1899
                            '.$item['title'].'
1900
                            </a>
1901
                          </div>';
1902
1903
                $html .= '<div id="collapse'.$count.'" class="accordion-body">';
1904
                $html .= '<div class="accordion-my-inner">
1905
                            '.$item['content'].'
1906
                            </div>
1907
                          </div>';
1908
            }
1909
            $html .= '</div>';
1910
        }
1911
1912
        return $html;
1913
    }
1914
1915
    /**
1916
     * @todo use twig
1917
     */
1918
    public static function group_button($title, $elements)
1919
    {
1920
        $html = '<div class="btn-group">
1921
                <button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
1922
                '.$title.'
1923
                <span class="caret"></span></button>
1924
                <ul class="dropdown-menu">';
1925
        foreach ($elements as $item) {
1926
            $html .= Display::tag('li', Display::url($item['title'], $item['href']));
1927
        }
1928
        $html .= '</ul>
1929
            </div>';
1930
        return $html;
1931
    }
1932
1933
    /**
1934
     * @param string $file
1935
     * @param array $params
1936
     * @return null|string
1937
     */
1938
    public static function getMediaPlayer($file, $params = array())
1939
    {
1940
        $fileInfo = pathinfo($file);
1941
1942
        switch ($fileInfo['extension']) {
1943
            case 'mp3':
1944
            case 'webm':
1945
                $autoplay = null;
1946
                if (isset($params['autoplay']) && $params['autoplay'] == 'true') {
1947
                    $autoplay = 'autoplay';
1948
                }
1949
                $width = isset($params['width']) ? 'width="'.$params['width'].'"' : null;
1950
                $id = isset($params['id']) ? $params['id'] : $fileInfo['basename'];
1951
                $class = isset($params['class']) ? ' class="'.$params['class'].'"' : null;
1952
1953
                $html = '<audio id="'.$id.'" '.$class.' controls '.$autoplay.' '.$width.' src="'.$params['url'].'" >';
1954
                $html .= '<object width="'.$width.'" height="50" type="application/x-shockwave-flash" data="'.api_get_path(WEB_LIBRARY_PATH).'javascript/mediaelement/flashmediaelement.swf">
1955
                            <param name="movie" value="'.api_get_path(WEB_LIBRARY_PATH).'javascript/mediaelement/flashmediaelement.swf" />
1956
                            <param name="flashvars" value="controls=true&file='.$params['url'].'" />
1957
                          </object>';
1958
                $html .= '</audio>';
1959
1960
                return $html;
1961
                break;
1962
            case 'wav':
1963
                //no break;
1964
            case 'ogg':
1965
                $html = '<audio width="300px" controls src="'.$params['url'].'" >';
1966
1967
                return $html;
1968
                break;
1969
        }
1970
1971
        return null;
1972
    }
1973
1974
    /**
1975
     *
1976
     * @param int $nextValue
1977
     * @param array $list
1978
     * @param int $current
1979
     * @param int $fixedValue
1980
     * @param array $conditions
1981
     * @param string $link
1982
     * @param bool $isMedia
1983
     * @param bool $addHeaders
1984
     * @return string
1985
     */
1986
    public static function progressPaginationBar(
1987
        $nextValue,
1988
        $list,
1989
        $current,
1990
        $fixedValue = null,
1991
        $conditions = array(),
1992
        $link = null,
1993
        $isMedia = false,
1994
        $addHeaders = true,
1995
        $linkAttributes = array()
1996
    ) {
1997
        if ($addHeaders) {
1998
            $pagination_size = 'pagination-mini';
1999
            $html = '<div class="exercise_pagination pagination '.$pagination_size.'"><ul>';
2000
        } else {
2001
            $html = null;
2002
        }
2003
        $affectAllItems = false;
2004
        if ($isMedia && isset($fixedValue) && ($nextValue + 1 == $current)) {
2005
            $affectAllItems = true;
2006
        }
2007
        $localCounter = 0;
2008
        foreach ($list as $itemId) {
2009
            $isCurrent = false;
2010
            if ($affectAllItems) {
2011
                $isCurrent = true;
2012
            } else {
2013
                if (!$isMedia) {
2014
                    $isCurrent = $current == ($localCounter + $nextValue + 1) ? true : false;
2015
                }
2016
            }
2017
            $html .= self::parsePaginationItem(
2018
                $itemId,
2019
                $isCurrent,
2020
                $conditions,
2021
                $link,
2022
                $nextValue,
2023
                $isMedia,
2024
                $localCounter,
2025
                $fixedValue,
2026
                $linkAttributes
2027
            );
2028
            $localCounter++;
2029
        }
2030
        if ($addHeaders) {
2031
            $html .= '</ul></div>';
2032
        }
2033
        return $html;
2034
    }
2035
    /**
2036
     *
2037
     * @param int $itemId
2038
     * @param bool $isCurrent
2039
     * @param array $conditions
2040
     * @param string $link
2041
     * @param int $nextValue
2042
     * @param bool $isMedia
2043
     * @param int $localCounter
2044
     * @param int $fixedValue
2045
     * @return string
2046
     */
2047
    public static function parsePaginationItem(
2048
        $itemId,
2049
        $isCurrent,
2050
        $conditions,
2051
        $link,
2052
        $nextValue = 0,
2053
        $isMedia = false,
2054
        $localCounter = null,
2055
        $fixedValue = null,
2056
        $linkAttributes = array())
2057
    {
2058
        $defaultClass = "before";
2059
        $class = $defaultClass;
2060
        foreach ($conditions as $condition) {
2061
            $array = isset($condition['items']) ? $condition['items'] : array();
2062
            $class_to_applied = $condition['class'];
2063
            $type = isset($condition['type']) ? $condition['type'] : 'positive';
2064
            $mode = isset($condition['mode']) ? $condition['mode'] : 'add';
2065
            switch ($type) {
2066 View Code Duplication
                case 'positive':
2067
                    if (in_array($itemId, $array)) {
2068
                        if ($mode == 'overwrite') {
2069
                            $class = " $defaultClass $class_to_applied";
2070
                        } else {
2071
                            $class .= " $class_to_applied";
2072
                        }
2073
                    }
2074
                    break;
2075 View Code Duplication
                case 'negative':
2076
                    if (!in_array($itemId, $array)) {
2077
                        if ($mode == 'overwrite') {
2078
                            $class = " $defaultClass $class_to_applied";
2079
                        } else {
2080
                            $class .= " $class_to_applied";
2081
                        }
2082
                    }
2083
                    break;
2084
            }
2085
        }
2086
        if ($isCurrent) {
2087
            $class = "before current";
2088
        }
2089
        if ($isMedia && $isCurrent) {
2090
            $class = "before current";
2091
        }
2092
        if (empty($link)) {
2093
            $link_to_show = "#";
2094
        } else {
2095
            $link_to_show = $link.($nextValue + $localCounter);
2096
        }
2097
        $label = $nextValue + $localCounter + 1;
2098
        if ($isMedia) {
2099
            $label = ($fixedValue + 1) .' '.chr(97 + $localCounter);
2100
            $link_to_show = $link.$fixedValue.'#questionanchor'.$itemId;
2101
        }
2102
        $link = Display::url($label.' ', $link_to_show, $linkAttributes);
2103
        return  '<li class = "'.$class.'">'.$link.'</li>';
2104
    }
2105
2106
    /**
2107
     * @param int $current
2108
     * @param int $total
2109
     * @return string
2110
     */
2111
    public static function paginationIndicator($current, $total)
2112
    {
2113
        $html = null;
2114
        if (!empty($current) && !empty($total)) {
2115
            $label = sprintf(get_lang('PaginationXofY'), $current, $total);
2116
            $html = self::url($label, '#', array('class' => 'btn disabled'));
2117
        }
2118
        return $html;
2119
    }
2120
2121
    /**
2122
     * Adds a message in the queue
2123
     * @param string $message
2124
     */
2125
    public static function addFlash($message)
2126
    {
2127
        $messages = Session::read('flash_messages');
2128
        if (empty($messages)) {
2129
            $messages[] = $message;
2130
        } else {
2131
            array_push($messages, $message);
2132
        }
2133
        Session::write('flash_messages', $messages);
2134
    }
2135
2136
    /**
2137
     * @return string
2138
     */
2139
    public static function getFlashToString()
2140
    {
2141
        $messages = Session::read('flash_messages');
2142
        $messageToString = '';
2143
        if (!empty($messages)) {
2144
            foreach ($messages as $message) {
2145
                $messageToString .= $message;
2146
            }
2147
        }
2148
2149
        return $messageToString;
2150
    }
2151
2152
    /**
2153
     * Shows the message from the session
2154
     */
2155
    public static function showFlash()
2156
    {
2157
        echo self::getFlashToString();
2158
    }
2159
2160
    /**
2161
     * Destroys the message session
2162
     */
2163
    public static function cleanFlashMessages()
2164
    {
2165
        Session::erase('flash_messages');
2166
    }
2167
2168
    /**
2169
     * Get the profile edition link for a user
2170
     * @param int $userId The user id
2171
     * @param boolean $asAdmin Optional. Whether get the URL for the platform admin
2172
     * @return string The link
2173
     */
2174
    public static function getProfileEditionLink($userId, $asAdmin = false)
2175
    {
2176
        $editProfileUrl = api_get_path(WEB_CODE_PATH).'auth/profile.php';
2177
2178
        if ($asAdmin) {
2179
            $editProfileUrl = api_get_path(WEB_CODE_PATH)."admin/user_edit.php?user_id=".intval($userId);
2180
        }
2181
2182
        if (api_get_setting('sso_authentication') === 'true') {
2183
            $subSSOClass = api_get_setting('sso_authentication_subclass');
2184
2185
            $objSSO = null;
2186
2187
            if (!empty($subSSOClass)) {
2188
                $file = api_get_path(SYS_CODE_PATH)."auth/sso/sso.$subSSOClass.class.php";
2189
                if (file_exists($file)) {
2190
                    require_once $file;
2191
                    $subSSOClass = 'sso'.$subSSOClass;
2192
                    $objSSO = new $subSSOClass();
2193
                } else {
2194
                    throw new Exception("$subSSOClass file not set");
2195
                }
2196
            } else {
2197
                $objSSO = new sso();
2198
            }
2199
2200
            $editProfileUrl = $objSSO->generateProfileEditingURL(
2201
                $userId,
2202
                $asAdmin
2203
            );
2204
        }
2205
2206
        return $editProfileUrl;
2207
    }
2208
2209
    /**
2210
     * Get the vCard for a user
2211
     * @param int $userId The user id
2212
     * @return string *.*vcf file
2213
     */
2214
    public static function getVCardUserLink($userId)
2215
    {
2216
        $vCardUrl = api_get_path(WEB_PATH).'main/social/vcard_export.php?userId='.intval($userId);
2217
2218
        return $vCardUrl;
2219
    }
2220
2221
    /**
2222
     * @param string $content
2223
     * @param string $title
2224
     * @param string $footer
2225
     * @param string $style primary|success|info|warning|danger
2226
     * @param string $extra
2227
     *
2228
     * @return string
2229
     */
2230
    public static function panel($content, $title = '', $footer = '', $style = '', $extra = '')
2231
    {
2232
        $title = !empty($title) ? '<div class="panel-heading"><h3 class="panel-title">'.$title.'</h3>'.$extra.'</div>' : '';
2233
        $footer = !empty($footer) ? '<div class="panel-footer ">'.$footer.'</div>' : '';
2234
        $styles = ['primary', 'success', 'info', 'warning', 'danger'];
2235
        $style = !in_array($style, $styles) ? 'default' : $style;
2236
2237
        return '
2238
            <div class="panel panel-'.$style.'">
2239
                '.$title.'
2240
                '.self::contentPanel($content).'
2241
                '.$footer.'
2242
            </div>'
2243
        ;
2244
    }
2245
2246
    /**
2247
     * @param string $content
2248
     * @return string
2249
     */
2250
    public static function contentPanel($content)
2251
    {
2252
        return '<div class="panel-body">
2253
                '.$content.'
2254
                </div>';
2255
    }
2256
2257
    /**
2258
     * Get the button HTML with an Awesome Font icon
2259
     * @param string $text The button content
2260
     * @param string $url The url to button
2261
     * @param string $icon The Awesome Font class for icon
2262
     * @param string $type Optional. The button Bootstrap class. Default 'default' class
2263
     * @param array $attributes The additional attributes
2264
     * @return string The button HTML
2265
     */
2266
    public static function toolbarButton(
2267
        $text,
2268
        $url,
2269
        $icon = 'check',
2270
        $type = 'default',
2271
        array $attributes = [],
2272
        $includeText = true
2273
    ) {
2274
        $buttonClass = "btn btn-$type";
2275
        $icon = self::tag('i', null, ['class' => "fa fa-$icon fa-fw", 'aria-hidden' => 'true']);
2276
        $attributes['class'] = isset($attributes['class']) ? "$buttonClass {$attributes['class']}" : $buttonClass;
2277
        $attributes['title'] = isset($attributes['title']) ? $attributes['title'] : $text;
2278
2279
        if (!$includeText) {
2280
            $text = '<span class="sr-only">' . $text . '</span>';
2281
        }
2282
2283
        return self::url("$icon $text", $url, $attributes);
2284
    }
2285
2286
    /**
2287
     * @param int $id
2288
     * @param array $content
2289
     * @param int $col
2290
     * @param bool|true $right
2291
     * @return string
2292
     */
2293
    public static function toolbarAction($id, $content = array(), $col = 2, $right = true)
2294
    {
2295
        $columns = 12/$col;
2296
        $html = '';
2297
        $html .= '<div id="' . $id . '" class="actions">';
2298
        $html .= '<div class="row">';
2299
        if ($col > 4) {
2300
            $html = '<div class="alert alert-warning" role="alert">
2301
                Action toolbar design does not work when exceeding four columns - check Display::toolbarAction()
2302
            </div>';
2303
        } else {
2304
            for ($i = 0; $i < $col; $i++) {
2305
                $html .= '<div class="col-md-' . $columns . '">';
2306
                if ($col == 2 && $i == 1) {
2307
                    if ($right === true) {
2308
                        $html .= '<div class="pull-right">';
2309
                        $html .= (isset($content[$i]) ? $content[$i] : '');
2310
                        $html .= '</div>';
2311
                    } else {
2312
                        $html .= $content[$i];
2313
                    }
2314
                } else {
2315
                    $html .= $content[$i];
2316
                }
2317
                $html .= '</div>';
2318
            }
2319
        }
2320
        $html .= '</div>';
2321
        $html .= '</div>';
2322
2323
        return $html;
2324
    }
2325
2326
    /**
2327
     * Get a HTML code for a icon by Font Awesome
2328
     * @param string $name The icon name
2329
     * @param int|string $size Optional. The size for the icon. (Example: lg, 2, 3, 4, 5)
2330
     * @param boolean $fixWidth Optional. Whether add the fw class
2331
     * @param string $additionalClass Optional. Additional class
2332
     *
2333
     * @return string
2334
     */
2335
    public static function returnFontAwesomeIcon(
2336
        $name,
2337
        $size = '',
2338
        $fixWidth = false,
2339
        $additionalClass = ''
2340
    ) {
2341
        $className = "fa fa-$name";
2342
2343
        if ($fixWidth) {
2344
            $className .= ' fa-fw';
2345
        }
2346
2347
        switch ($size) {
2348
            case 'lg':
2349
                $className .= ' fa-lg';
2350
                break;
2351
            case 2:
2352
                //no break
2353
            case 3:
2354
                //no break
2355
            case 4:
2356
                //no break
2357
            case 5:
2358
                $className .= " fa-{$size}x";
2359
                break;
2360
        }
2361
2362
        if (!empty($additionalClass)) {
2363
            $className .= " $additionalClass";
2364
        }
2365
2366
        $icon = self::tag('em', null, ['class' => $className]);
2367
2368
        return "$icon ";
2369
    }
2370
2371
    /**
2372
     * @param string $title
2373
     * @param string $content
2374
     * @param null $id
2375
     * @param array $params
2376
     * @param null $idAccordion
2377
     * @param null $idCollapse
2378
     * @param bool|true $open
2379
     * @param bool|false $fullClickable
2380
     * @return null|string
2381
     */
2382
    public static function panelCollapse(
2383
        $title,
2384
        $content,
2385
        $id = null,
2386
        $params = array(),
2387
        $idAccordion = null,
2388
        $idCollapse = null,
2389
        $open = true,
2390
        $fullClickable = false
2391
    ) {
2392
        if (!empty($idAccordion)) {
2393
            $headerClass = '';
2394
            $headerClass .= $fullClickable ? 'center-block ' : '';
2395
            $headerClass .= $open ? '' : 'collapsed';
2396
            $contentClass = 'panel-collapse collapse ';
2397
            $contentClass .= $open ? 'in' : '';
2398
            $ariaExpanded = $open ? 'true' : 'false';
2399
2400
            $html = <<<HTML
2401
                <div class="panel-group" id="$idAccordion" role="tablist" aria-multiselectable="true">
2402
                    <div class="panel panel-default" id="$id">
2403
                        <div class="panel-heading" role="tab">
2404
                            <h4 class="panel-title">
2405
                                <a class="$headerClass" role="button" data-toggle="collapse" data-parent="#$idAccordion" href="#$idCollapse" aria-expanded="$ariaExpanded" aria-controls="$idCollapse">$title</a>
2406
                            </h4>
2407
                        </div>
2408
                        <div id="$idCollapse" class="$contentClass" role="tabpanel">
2409
                            <div class="panel-body">$content</div>
2410
                        </div>
2411
                    </div>
2412
                </div>
2413
HTML;
2414 View Code Duplication
        } else {
2415
            if (!empty($id)) {
2416
                $params['id'] = $id;
2417
            }
2418
            $params['class'] = 'panel panel-default';
2419
            $html = null;
2420
            if (!empty($title)) {
2421
                $html .= '<div class="panel-heading">'.$title.'</div>' . PHP_EOL;
2422
            }
2423
            $html.= '<div class="panel-body">'.$content.'</div>' . PHP_EOL;
2424
            $html = Display::div($html, $params);
2425
        }
2426
        return $html;
2427
    }
2428
2429
    /**
2430
     * Returns the string "1 day ago" with a link showing the exact date time.
2431
     * @param string $dateTime in UTC
2432
     *
2433
     * @return string
2434
     */
2435
    public static function dateToStringAgoAndLongDate($dateTime)
2436
    {
2437
        if (empty($dateTime) || $dateTime === '0000-00-00 00:00:00') {
2438
            return '';
2439
        }
2440
2441
        return self::tip(
2442
            date_to_str_ago($dateTime),
2443
            api_get_local_time($dateTime)
2444
        );
2445
    }
2446
}
2447