Proyectos de Subversion Moodle

Rev

Rev 1317 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
namespace theme_universe\output;
18
 
19
use html_writer;
20
use stdClass;
21
use moodle_url;
22
use context_course;
23
use context_system;
24
use core_course_list_element;
25
use custom_menu;
1441 ariadna 26
use core_completion;
1 efrain 27
use action_menu_filler;
28
use action_menu_link_secondary;
29
use action_menu;
30
use action_link;
31
use core_text;
32
use coding_exception;
33
use navigation_node;
34
use context_header;
35
use pix_icon;
36
use renderer_base;
37
use theme_config;
38
use get_string;
39
use core_course_category;
40
use theme_universe\util\user;
41
use theme_universe\util\course;
42
 
43
/**
44
 * Renderers to align Moodle's HTML with that expected by Bootstrap
45
 *
46
 * @package    theme_universe
47
 * @copyright  2023 Marcin Czaja (https://rosea.io)
48
 * @license    Commercial https://themeforest.net/licenses
49
 */
1441 ariadna 50
class core_renderer extends \core_renderer {
1 efrain 51
 
1441 ariadna 52
    public function edit_button(moodle_url $url, string $method = 'post') {
1 efrain 53
        if ($this->page->theme->haseditswitch) {
54
            return;
55
        }
56
        $url->param('sesskey', sesskey());
57
        if ($this->page->user_is_editing()) {
58
            $url->param('edit', 'off');
59
            $editstring = get_string('turneditingoff');
60
        } else {
61
            $url->param('edit', 'on');
62
            $editstring = get_string('turneditingon');
63
        }
64
        $button = new \single_button($url, $editstring, 'post', ['class' => 'btn btn-primary']);
65
        return $this->render_single_button($button);
66
    }
67
 
68
    /**
69
     * The standard tags (meta tags, links to stylesheets and JavaScript, etc.)
70
     * that should be included in the <head> tag. Designed to be called in theme
71
     * layout.php files.
72
     *
73
     * @return string HTML fragment.
74
     */
1441 ariadna 75
    public function standard_head_html() {
1 efrain 76
        $output = parent::standard_head_html();
77
        global $USER;
78
 
79
        $googleanalyticscode = "<script
80
                                    async
81
                                    src='https://www.googletagmanager.com/gtag/js?id=GOOGLE-ANALYTICS-CODE'>
82
                                </script>
83
                                <script>
84
                                    window.dataLayer = window.dataLayer || [];
85
                                    function gtag() {
86
                                        dataLayer.push(arguments);
87
                                    }
88
                                    gtag('js', new Date());
89
                                    gtag('config', 'GOOGLE-ANALYTICS-CODE');
90
                                </script>";
91
 
92
        $theme = theme_config::load('universe');
93
 
94
        if (!empty($theme->settings->googleanalytics) && isloggedin()) {
95
            $output .= str_replace(
96
                "GOOGLE-ANALYTICS-CODE",
97
                trim($theme->settings->googleanalytics),
98
                $googleanalyticscode
99
            );
100
        }
101
 
102
        return $output;
103
    }
104
 
1441 ariadna 105
    /*
106
    *
107
    * Method to get reference to $CFG->themedir variable
108
    *
109
    */
110
    function theme_universe_themedir() {
111
        global $CFG;
1 efrain 112
 
1441 ariadna 113
        $teme_dir = '/theme';
114
 
115
        if (isset($CFG->themedir)) {
116
            $teme_dir = $CFG->themedir;
117
            $teme_dir = str_replace($CFG->dirroot, '', $CFG->themedir);
118
        }
119
 
120
        return $teme_dir;
121
    }
122
 
123
 
1 efrain 124
    /**
125
     *
126
     * Method to load theme element form 'layout/parts' folder
127
     *
128
     */
1441 ariadna 129
    public function theme_part($name, $vars = array()) {
1 efrain 130
 
131
        global $CFG;
132
 
133
        $element = $name . '.php';
134
        $candidate1 = $this->page->theme->dir . '/layout/parts/' . $element;
135
 
136
        // Require for child theme.
137
        if (file_exists($candidate1)) {
138
            $candidate = $candidate1;
139
        } else {
140
            $candidate = $CFG->dirroot . theme_universe_themedir() . '/universe/layout/parts/' . $element;
141
        }
142
 
143
        if (!is_readable($candidate)) {
144
            debugging("Could not include element $name.");
145
            return;
146
        }
147
 
148
        ob_start();
149
        include($candidate);
150
        $output = ob_get_clean();
151
        return $output;
152
    }
153
 
154
    /**
155
     * Renders the custom menu
156
     *
157
     * @param custom_menu $menu
158
     * @return mixed
159
     */
1441 ariadna 160
    protected function render_custom_menu(custom_menu $menu) {
1 efrain 161
        if (!$menu->has_children()) {
162
            return '';
163
        }
164
 
165
        $content = '';
166
        foreach ($menu->get_children() as $item) {
167
            $context = $item->export_for_template($this);
168
            $content .= $this->render_from_template('core/moremenu_children', $context);
169
        }
170
 
171
        return $content;
172
    }
173
 
174
    /**
175
     * Outputs the favicon urlbase.
176
     *
177
     * @return string an url
178
     */
1441 ariadna 179
    public function favicon() {
1 efrain 180
        global $CFG;
181
        $theme = theme_config::load('universe');
182
        $favicon = $theme->setting_file_url('favicon', 'favicon');
183
 
184
        if (!empty(($favicon))) {
185
            $urlreplace = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
186
            $favicon = str_replace($urlreplace, '', $favicon);
187
 
188
            return new moodle_url($favicon);
189
        }
190
 
191
        return parent::favicon();
192
    }
193
 
1441 ariadna 194
    public function render_lang_menu() {
1 efrain 195
        $langs = get_string_manager()->get_list_of_translations();
196
        $haslangmenu = $this->lang_menu() != '';
197
        $menu = new custom_menu;
198
 
199
        if ($haslangmenu) {
200
            $strlang = get_string('language');
201
            $currentlang = current_language();
202
            if (isset($langs[$currentlang])) {
203
                $currentlang = $langs[$currentlang];
204
            } else {
205
                $currentlang = $strlang;
206
            }
207
            $this->language = $menu->add($currentlang, new moodle_url('#'), $strlang, 10000);
208
            foreach ($langs as $langtype => $langname) {
209
                $this->language->add($langname, new moodle_url($this->page->url, array('lang' => $langtype)), $langname);
210
            }
211
            foreach ($menu->get_children() as $item) {
212
                $context = $item->export_for_template($this);
213
            }
214
 
215
            $context->currentlangname = array_search($currentlang, $langs);
216
 
217
            if (isset($context)) {
218
                return $this->render_from_template('theme_universe/lang_menu', $context);
219
            }
220
        }
221
    }
222
 
1441 ariadna 223
    public function render_lang_menu_login() {
1 efrain 224
        $langs = get_string_manager()->get_list_of_translations();
225
        $haslangmenu = $this->lang_menu() != '';
226
        $menu = new custom_menu;
227
 
228
        if ($haslangmenu) {
229
            $strlang = get_string('language');
230
            $currentlang = current_language();
231
            if (isset($langs[$currentlang])) {
232
                $currentlang = $langs[$currentlang];
233
            } else {
234
                $currentlang = $strlang;
235
            }
236
            $this->language = $menu->add($currentlang, new moodle_url('#'), $strlang, 10000);
237
            foreach ($langs as $langtype => $langname) {
238
                $this->language->add($langname, new moodle_url($this->page->url, array('lang' => $langtype)), $langname);
239
            }
240
            foreach ($menu->get_children() as $item) {
241
                $context = $item->export_for_template($this);
242
            }
243
 
244
            $context->currentlangname = array_search($currentlang, $langs);
245
 
246
            if (isset($context)) {
247
                return $this->render_from_template('theme_universe/lang_menu_login', $context);
248
            }
249
        }
250
    }
251
 
1441 ariadna 252
    public static function get_course_progress_count($course, $userid = 0) {
1 efrain 253
        global $USER;
254
 
255
        // Make sure we continue with a valid userid.
256
        if (empty($userid)) {
257
            $userid = $USER->id;
258
        }
259
 
260
        $completion = new \completion_info($course);
261
 
262
        // First, let's make sure completion is enabled.
263
        if (!$completion->is_enabled()) {
264
            return null;
265
        }
266
 
267
        if (!$completion->is_tracked_user($userid)) {
268
            return null;
269
        }
270
 
271
        // Before we check how many modules have been completed see if the course has.
272
        if ($completion->is_course_complete($userid)) {
273
            return 100;
274
        }
275
 
276
        // Get the number of modules that support completion.
277
        $modules = $completion->get_activities();
278
        $count = count($modules);
279
        if (!$count) {
280
            return null;
281
        }
282
 
283
        // Get the number of modules that have been completed.
284
        $completed = 0;
285
        foreach ($modules as $module) {
286
            $data = $completion->get_data($module, true, $userid);
287
            $completed += $data->completionstate == COMPLETION_INCOMPLETE ? 0 : 1;
288
        }
289
 
290
        return ($completed / $count) * 100;
291
    }
292
 
293
    /**
294
     *
295
     * Outputs the course progress if course completion is on.
296
     *
297
     * @return string Markup.
298
     */
1441 ariadna 299
    protected function courseprogress($course) {
1 efrain 300
        global $USER;
301
        $theme = \theme_config::load('universe');
302
 
303
        $output = '';
304
        $courseformat = course_get_format($course);
305
 
306
        if (get_class($courseformat) != 'format_tiles') {
307
            $completion = new \completion_info($course);
308
 
309
            // Start Course progress count.
310
            // Make sure we continue with a valid userid.
311
            if (empty($userid)) {
312
                $userid = $USER->id;
313
            }
314
            $completion = new \completion_info($course);
315
 
316
            // Get the number of modules that support completion.
317
            $modules = $completion->get_activities();
318
            $count = count($modules);
1441 ariadna 319
 
1 efrain 320
            if (!$count) {
321
                return null;
322
            }
323
 
324
            // Get the number of modules that have been completed.
325
            $completed = 0;
326
            foreach ($modules as $module) {
327
                $data = $completion->get_data($module, true, $userid);
328
                $completed += $data->completionstate == COMPLETION_INCOMPLETE ? 0 : 1;
329
            }
330
            $progresscountc = $completed;
331
            $progresscounttotal = $count;
332
            // End progress count.
333
 
334
            if ($completion->is_enabled()) {
335
                $templatedata = new \stdClass;
336
                $templatedata->progress = \core_completion\progress::get_course_progress_percentage($course);
337
                $templatedata->progresscountc = $progresscountc;
338
                $templatedata->progresscounttotal = $progresscounttotal;
339
 
340
                if (!is_null($templatedata->progress)) {
341
                    $templatedata->progress = floor($templatedata->progress);
342
                } else {
343
                    $templatedata->progress = 0;
344
                }
345
                if (get_config('theme_universe', 'courseprogressbar') == 1) {
346
                    $progressbar = '<div class="rui-course-progresschart">' .
347
                        $this->render_from_template('theme_universe/progress-chart', $templatedata) .
348
                        '</div>';
349
                    if (has_capability('report/progress:view',  \context_course::instance($course->id))) {
350
                        $courseprogress = new \moodle_url('/report/progress/index.php');
351
                        $courseprogress->param('course', $course->id);
352
                        $courseprogress->param('sesskey', sesskey());
353
                        $output .= html_writer::link($courseprogress, $progressbar, array('class' => 'rui-course-progressbar border rounded px-3 pt-2 mb-3'));
354
                    } else {
355
                        $output .= $progressbar;
356
                    }
357
                }
358
            }
359
        }
360
 
361
        return $output;
362
    }
363
 
364
 
365
    /**
366
     *
367
     * Returns HTML to display course contacts.
368
     *
369
     */
1441 ariadna 370
    public function course_teachers() {
1 efrain 371
        global $CFG, $COURSE, $DB;
372
        $course = $DB->get_record('course', ['id' => $COURSE->id]);
373
        $course = new core_course_list_element($course);
374
        $instructors = $course->get_course_contacts();
375
 
376
        if (!empty($instructors)) {
377
            $content = html_writer::start_div('course-teachers-box');
378
 
379
            foreach ($instructors as $key => $instructor) {
380
                $name = $instructor['username'];
381
                $role = $instructor['rolename'];
382
                $roleshortname = $instructor['role']->shortname;
383
 
384
                if ($instructor['role']->id == '3') {
385
                    $url = $CFG->wwwroot . '/user/profile.php?id=' . $key;
386
                    $user = $instructor['user'];
387
                    $userutil = new user($user->id);
388
                    $picture = $userutil->get_user_picture();
389
 
390
                    $content .= "<div class='course-contact-title-item'>
391
                        <a href='{$url}' 'title='{$name}'
392
                            class='course-contact rui-user-{$roleshortname}'>";
393
                    $content .= "<img src='{$picture}'
394
                        class='course-teacher-avatar' alt='{$name}'
1441 ariadna 395
                        title='{$name} - {$role}' data-bs-toggle='tooltip'/>";
1 efrain 396
                    $content .= "<div class='course-teacher-content'>
397
                        <span class='course-teacher-role'>{$role}</span>
398
                        <h4 class='course-teacher-name'>{$name}</h4></div>";
399
                    $content .= "</a></div>";
400
                }
401
            }
402
 
403
            $content .= html_writer::end_div(); // End .teachers-box.
404
            return $content;
405
        }
406
    }
407
 
1441 ariadna 408
    public function course_contacts() {
1 efrain 409
        global $CFG, $COURSE, $DB;
410
        $course = $DB->get_record('course', ['id' => $COURSE->id]);
411
        $course = new core_course_list_element($course);
412
        $instructors = $course->get_course_contacts();
413
 
414
        if (!empty($instructors)) {
1441 ariadna 415
            $content = '';
1 efrain 416
 
417
            foreach ($instructors as $key => $instructor) {
418
                $name = $instructor['username'];
419
                $role = $instructor['rolename'];
420
                $roleshortname = $instructor['role']->shortname;
421
 
422
                $url = $CFG->wwwroot . '/user/profile.php?id=' . $key;
423
                $user = $instructor['user'];
424
                $userutil = new user($user->id);
425
                $picture = $userutil->get_user_picture(384);
426
 
427
                $user = $DB->get_record('user', array('id' => $key));
428
                $desc = $user->description;
429
 
1441 ariadna 430
                $content .= "<div class='course-teachers-box my-0'>";
431
                $content .= "<div class='course-contact course-teacher-avatar mt-0'><img src='{$picture}'
432
                    class='course-teacher-avatar'
1 efrain 433
                    alt='{$name}, {$role}'/></div>";
1441 ariadna 434
                $content .= "<div class='course-contact-title-item d-block'>
435
                    <span class='course-teacher-role d-block'>{$role}</span>
1 efrain 436
                    <a href='{$url}' 'title='{$name}'
1441 ariadna 437
                        class='d-flex flex-wrap course-contact rui-user-{$roleshortname}'>
438
                        <h4 class='course-teacher-name mb-0'>{$name}</h4></a></div>";
439
                $content .= "<div class='rui-course-contact-desc'>{$desc}</div></div>";
1 efrain 440
            }
1441 ariadna 441
 
1 efrain 442
            return $content;
443
        }
444
    }
445
 
446
    /**
447
     *
448
     * Returns HTML to display course details.
449
     *
450
     */
1441 ariadna 451
    protected function course_details() {
1 efrain 452
        global $CFG, $COURSE, $DB;
453
 
1441 ariadna 454
        if ($this->page->theme->settings->ipcoursedates == 1) {
455
            $course = $DB->get_record('course', ['id' => $COURSE->id]);
456
            $course = new core_course_list_element($course);
457
            $content = '';
458
            $tempcourse = $DB->get_record('course_categories', ['id' => $COURSE->id]);
459
 
460
            $content .= html_writer::start_div('rui-course-details d-flex');
1 efrain 461
            $content .= html_writer::start_div('rui-custom-field-box rui-course-startdate');
1441 ariadna 462
            $content .= html_writer::tag('span', get_string('startdate', 'moodle'), ['class' => 'rui-custom-field-name']);
463
            $content .= html_writer::tag('span', userdate($course->startdate, get_string('strftimedaydate', 'core_langconfig')), ['class' => 'rui-custom-field-value']);
1 efrain 464
            $content .= html_writer::end_div();
1441 ariadna 465
 
466
            // Course End date.
467
            $courseenddate = $COURSE->enddate;
468
            if ($courseenddate != '0') {
469
                $content .= html_writer::start_div('rui-custom-field-box rui-course-startdate');
470
                $content .= html_writer::tag('span', get_string('enddate', 'moodle'), ['class' => 'rui-course-enddate-label rui-custom-field-name']);
471
                $content .= html_writer::tag('span', userdate($courseenddate, get_string('strftimedaydate', 'core_langconfig')), ['class' => 'rui-course-enddate rui-custom-field-value']);
472
                $content .= html_writer::end_div();
473
            }
474
            $content .= html_writer::end_div(); // .rui-course-details.
475
 
476
            return $content;
161 ariadna 477
        }
1 efrain 478
 
479
    }
480
 
481
    /**
482
     *
483
     * Returns HTML to display course summary.
484
     *
485
     */
1441 ariadna 486
    protected function course_summary($courseid = 0, $content = '') {
1 efrain 487
        global $COURSE, $CFG;
488
        $output = '';
489
 
490
        require_once($CFG->libdir . '/filelib.php');
491
 
492
        $iscourseid = $courseid ? $courseid : $COURSE->id;
493
        $iscontent = $content ? $content : $COURSE->summary;
494
        $context = context_course::instance($iscourseid);
495
        $desc = file_rewrite_pluginfile_urls($iscontent, 'pluginfile.php', $context->id, 'course', 'summary', null);
496
 
497
        $output .= html_writer::start_div('rui-course-desc');
498
        $output .= format_text($desc, FORMAT_HTML);
499
        $output .= html_writer::end_div();
500
 
501
        return $output;
502
    }
503
 
504
    /**
505
     * Outputs the pix url base
506
     *
507
     * @return string an URL.
508
     */
1441 ariadna 509
    public function get_pix_image_url_base() {
1 efrain 510
        global $CFG;
511
 
512
        return $CFG->wwwroot . "/theme/universe/pix";
513
    }
514
 
515
    /**
516
     *
517
     */
1441 ariadna 518
    public function course_hero_url() {
1 efrain 519
        global $CFG, $COURSE, $DB;
520
 
521
        $course = $DB->get_record('course', ['id' => $COURSE->id]);
522
 
523
        $course = new core_course_list_element($course);
524
 
525
        $courseimage = '';
526
        $imageindex = 1;
527
        foreach ($course->get_course_overviewfiles() as $file) {
528
            $isimage = $file->is_valid_image();
529
 
530
            $url = new moodle_url("$CFG->wwwroot/pluginfile.php" . '/' .
531
                $file->get_contextid() . '/' . $file->get_component() . '/' .
532
                $file->get_filearea() .
533
                $file->get_filepath() .
534
                $file->get_filename(), ['forcedownload' => !$isimage]);
535
 
536
            if ($isimage) {
537
                $courseimage = $url;
538
            }
539
 
540
            if ($imageindex == 2) {
541
                break;
542
            }
543
 
544
            $imageindex++;
545
        }
546
 
547
        $html = '';
548
        // Create html for header.
549
        if (!empty($courseimage)) {
550
            $html .= $courseimage;
551
        }
552
        return $html;
553
    }
554
 
555
    /**
556
     * Returns HTML to display course hero.
557
     *
558
     */
1441 ariadna 559
    public function course_hero() {
1 efrain 560
        global $CFG, $COURSE, $DB;
561
 
562
        $course = $DB->get_record('course', ['id' => $COURSE->id]);
563
 
564
        $course = new core_course_list_element($course);
565
 
566
        $courseimage = '';
567
 
568
        $courseutil = new course($course);
569
        $courseimage = $courseutil->get_summary_image(false); // Remove repeatable pattern on the course page.
570
 
571
        $html = '';
572
        // Create html for header.
573
        if (!empty($courseimage)) {
574
            $html .= $courseimage;
575
        }
576
        return $html;
577
    }
578
 
579
 
580
    /**
581
     * Breadcrumbs
582
     *
583
     */
1441 ariadna 584
    public function breadcrumbs() {
1 efrain 585
        global $USER, $COURSE, $CFG;
586
 
587
        $header = new stdClass();
588
        $header->hasnavbar = empty($this->page->layout_options['nonavbar']);
589
        $header->navbar = $this->navbar();
590
        $header->courseheader = $this->course_header();
591
        $html = $this->render_from_template('theme_universe/breadcrumbs', $header);
592
 
593
        return $html;
594
    }
595
 
596
 
597
    /**
598
     * Wrapper for header elements.
599
     *
600
     * @return string HTML to display the main header.
601
     */
1441 ariadna 602
    public function simple_header() {
1 efrain 603
 
604
        global $USER, $COURSE, $CFG;
605
        $html = null;
606
 
607
        if (
608
            $this->page->include_region_main_settings_in_header_actions() &&
609
            !$this->page->blocks->is_block_present('settings')
610
        ) {
611
            // Only include the region main settings if the page has requested it and it doesn't already have
612
            // the settings block on it. The region main settings are included in the settings block and
613
            // duplicating the content causes behat failures.
614
            $this->page->add_header_action(html_writer::div(
615
                $this->region_main_settings_menu(),
616
                'd-print-none',
617
                ['id' => 'region-main-settings-menu']
618
            ));
619
        }
620
 
621
        $header = new stdClass();
622
        $header->settingsmenu = $this->context_header_settings_menu();
623
        $header->contextheader = $this->context_header();
624
        $header->hasnavbar = empty($this->page->layout_options['nonavbar']);
625
        $header->navbar = $this->navbar();
626
        $header->pageheadingbutton = $this->page_heading_button();
627
        $header->courseheader = $this->course_header();
628
        $header->headeractions = $this->page->get_header_actions();
629
 
630
        if ($this->page->pagelayout != 'admin') {
631
            $html .= $this->render_from_template('theme_universe/header', $header);
632
        }
633
 
634
        if ($this->page->pagelayout == 'admin') {
635
            $html .= $this->render_from_template('theme_universe/header_admin', $header);
636
        }
637
 
638
        return $html;
639
    }
640
 
1441 ariadna 641
 
642
 
643
 
644
    public function display_course_progress() {
1 efrain 645
        $html = null;
646
        $html .= $this->courseprogress($this->page->course);
647
        return $html;
648
    }
649
 
650
    /**
651
     * Wrapper for header elements.
652
     *
653
     * @return string HTML to display the main header.
654
     */
1441 ariadna 655
    public function full_header() {
1 efrain 656
        global $USER, $COURSE, $CFG;
657
        $html = null;
658
        $homepage = get_home_page();
659
        // Add a special case since /my/courses is a part of the /my subsystem.
660
        if ($homepage == HOMEPAGE_MY || $homepage == HOMEPAGE_MYCOURSES) {
661
            $homepagetype = 'my-index';
662
        } else if ($homepage == HOMEPAGE_SITE) {
663
            $homepagetype = 'site-index';
664
        }
665
        if (
666
            $this->page->include_region_main_settings_in_header_actions() &&
667
            !$this->page->blocks->is_block_present('settings')
668
        ) {
669
            // Only include the region main settings if the page has requested it and it doesn't already have
670
            // the settings block on it. The region main settings are included in the settings block and
671
            // duplicating the content causes behat failures.
672
            $this->page->add_header_action(html_writer::div(
673
                $this->region_main_settings_menu(),
674
                'd-print-none',
675
                ['id' => 'region-main-settings-menu']
676
            ));
677
        }
678
 
679
        $header = new stdClass();
680
        $header->settingsmenu = $this->context_header_settings_menu();
681
        $header->contextheader = $this->context_header();
682
        $header->hasnavbar = empty($this->page->layout_options['nonavbar']);
683
        $header->navbar = $this->navbar();
684
        $header->pageheadingbutton = $this->page_heading_button();
685
        $header->courseheader = $this->course_header();
686
        $header->headeractions = $this->page->get_header_actions();
687
 
688
        if ($this->page->theme->settings->ipcoursedetails == 1) {
1441 ariadna 689
            $html .= html_writer::start_tag('div', array('class' => 'rui-course-info-box'));
690
            $html .= html_writer::start_tag('div', array('class' => 'rui-cinfo-container d-flex flex-wrap'));
1 efrain 691
            $html .= $this->course_details();
1441 ariadna 692
            $html .= html_writer::start_tag('div', array('class' => 'rui-course-header-custom-f'));
693
            $courseutil = new course($COURSE);
694
            $html .= $courseutil->course_get_taux();
695
            $html .= html_writer::end_tag('div'); // .rui-course-header-custom-f.
696
            $html .= html_writer::end_tag('div');
697
            $html .= html_writer::end_tag('div');
1 efrain 698
        }
699
 
700
        $html .= $this->render_from_template('theme_universe/header', $header);
701
        if ($this->page->theme->settings->ipcoursesummary == 1) {
702
            $html .= $this->course_summary();
703
        }
704
 
705
        $html .= html_writer::start_tag('div', array('class' => 'rui-course-header-color'));
706
        if ($this->page->theme->settings->cccteachers == 1) {
707
            $html .= $this->course_teachers();
708
        }
709
 
710
        $html .= html_writer::end_tag('div'); // End .rui-course-header.
711
 
712
        return $html;
713
    }
714
 
1441 ariadna 715
    /**
716
     * Wrapper for header elements.
717
     *
718
     * @return string HTML to display the main header.
719
     */
720
    public function efull_header() {
721
        global $USER, $COURSE, $CFG;
1 efrain 722
 
1441 ariadna 723
        $html = null;
724
 
725
        $html .= html_writer::start_tag('div', array('class' => 'rui-course-header'));
726
 
727
        if ($this->page->theme->settings->ipcoursedetails == 1) {
728
            $html .= html_writer::start_tag('div', array('class' => 'rui-course-info-box'));
729
            $html .= html_writer::start_tag('div', array('class' => 'rui-course-header-custom-f'));
730
            $courseutil = new course($COURSE);
731
            $html .= $courseutil->course_get_taux();
732
            $html .= html_writer::end_tag('div'); // .rui-course-header-custom-f.
733
            $html .= $this->course_details();
734
            $html .= html_writer::end_tag('div');
735
        }
736
 
737
        if ($this->page->theme->settings->ecoursesummary == 1) {
738
            $html .= $this->course_summary();
739
        }
740
 
741
        $html .= html_writer::end_tag('div'); // Rui-course-header.
742
        $html .= $this->get_enrollfields();
743
 
744
        return $html;
745
    }
746
 
747
 
1 efrain 748
    /**
749
     * Wrapper for header elements.
750
     *
751
     * @return string HTML to display the main header.
752
     */
1441 ariadna 753
    public function clean_header() {
1 efrain 754
        global $USER, $COURSE, $CFG;
755
        $html = null;
1441 ariadna 756
 
1 efrain 757
        $homepage = get_home_page();
758
        // Add a special case since /my/courses is a part of the /my subsystem.
759
        if ($homepage == HOMEPAGE_MY || $homepage == HOMEPAGE_MYCOURSES) {
760
            $homepagetype = 'my-index';
761
        } else if ($homepage == HOMEPAGE_SITE) {
762
            $homepagetype = 'site-index';
763
        }
764
        if (
765
            $this->page->include_region_main_settings_in_header_actions() &&
766
            !$this->page->blocks->is_block_present('settings')
767
        ) {
768
            // Only include the region main settings if the page has requested it and it doesn't already have
769
            // the settings block on it. The region main settings are included in the settings block and
770
            // duplicating the content causes behat failures.
771
            $this->page->add_header_action(html_writer::div(
772
                $this->region_main_settings_menu(),
773
                'd-print-none',
774
                ['id' => 'region-main-settings-menu']
775
            ));
776
        }
777
 
778
        $header = new stdClass();
779
        $header->courseheader = $this->course_header();
780
        $header->headeractions = $this->page->get_header_actions();
781
 
782
        $html .= $this->render_from_template('theme_universe/header', $header);
783
 
784
        return $html;
785
    }
786
 
787
 
788
    /**
789
     * Returns standard navigation between activities in a course.
790
     *
791
     * @return string the navigation HTML.
792
     */
1441 ariadna 793
    public function activity_navigation() {
1 efrain 794
        // First we should check if we want to add navigation.
795
        $context = $this->page->context;
796
        if (($this->page->pagelayout !== 'incourse' && $this->page->pagelayout !== 'frametop')
797
            || $context->contextlevel != CONTEXT_MODULE
798
        ) {
799
            return '';
800
        }
801
        // If the activity is in stealth mode, show no links.
802
        if ($this->page->cm->is_stealth()) {
803
            return '';
804
        }
805
        $course = $this->page->cm->get_course();
806
        $courseformat = course_get_format($course);
807
 
808
        // Get a list of all the activities in the course.
809
        $modules = get_fast_modinfo($course->id)->get_cms();
810
        // Put the modules into an array in order by the position they are shown in the course.
811
        $mods = [];
812
        $activitylist = [];
813
        foreach ($modules as $module) {
814
            // Only add activities the user can access, aren't in stealth mode and have a url (eg. mod_label does not).
815
            if (!$module->uservisible || $module->is_stealth() || empty($module->url)) {
816
                continue;
817
            }
818
            $mods[$module->id] = $module;
819
            // No need to add the current module to the list for the activity dropdown menu.
820
            if ($module->id == $this->page->cm->id) {
821
                continue;
822
            }
823
            // Module name.
824
            $modname = $module->get_formatted_name();
825
            // Display the hidden text if necessary.
826
            if (!$module->visible) {
827
                $modname .= ' ' . get_string('hiddenwithbrackets');
828
            }
829
            // Module URL.
830
            $linkurl = new moodle_url($module->url, array('forceview' => 1));
831
            // Add module URL (as key) and name (as value) to the activity list array.
832
            $activitylist[$linkurl->out(false)] = $modname;
833
        }
834
        $nummods = count($mods);
835
        // If there is only one mod then do nothing.
836
        if ($nummods == 1) {
837
            return '';
838
        }
839
        // Get an array of just the course module ids used to get the cmid value based on their position in the course.
840
        $modids = array_keys($mods);
841
        // Get the position in the array of the course module we are viewing.
842
        $position = array_search($this->page->cm->id, $modids);
843
        $prevmod = null;
844
        $nextmod = null;
845
        // Check if we have a previous mod to show.
846
        if ($position > 0) {
847
            $prevmod = $mods[$modids[$position - 1]];
848
        }
849
        // Check if we have a next mod to show.
850
        if ($position < ($nummods - 1)) {
851
            $nextmod = $mods[$modids[$position + 1]];
852
        }
853
        $activitynav = new \core_course\output\activity_navigation($prevmod, $nextmod, $activitylist);
854
        $renderer = $this->page->get_renderer('core', 'course');
855
        return $renderer->render($activitynav);
856
    }
857
 
858
 
859
    /**
860
     * This is an optional menu that can be added to a layout by a theme. It contains the
861
     * menu for the course administration, only on the course main page.
862
     *
863
     * @return string
864
     */
1441 ariadna 865
    public function context_header_settings_menu() {
1 efrain 866
        $context = $this->page->context;
867
        $menu = new action_menu();
868
 
869
        $items = $this->page->navbar->get_items();
870
        $currentnode = end($items);
871
 
872
        $showcoursemenu = false;
873
        $showfrontpagemenu = false;
874
        $showusermenu = false;
875
 
876
        // We are on the course home page.
877
        if (($context->contextlevel == CONTEXT_COURSE) &&
878
            !empty($currentnode) &&
879
            ($currentnode->type == navigation_node::TYPE_COURSE || $currentnode->type == navigation_node::TYPE_SECTION)
880
        ) {
881
            $showcoursemenu = true;
882
        }
883
 
884
        $courseformat = course_get_format($this->page->course);
885
        // This is a single activity course format, always show the course menu on the activity main page.
886
        if (
887
            $context->contextlevel == CONTEXT_MODULE &&
888
            !$courseformat->has_view_page()
889
        ) {
890
 
891
            $this->page->navigation->initialise();
892
            $activenode = $this->page->navigation->find_active_node();
893
            // If the settings menu has been forced then show the menu.
894
            if ($this->page->is_settings_menu_forced()) {
895
                $showcoursemenu = true;
896
            } else if (!empty($activenode) && ($activenode->type == navigation_node::TYPE_ACTIVITY ||
897
                $activenode->type == navigation_node::TYPE_RESOURCE)) {
898
 
899
                // We only want to show the menu on the first page of the activity. This means
900
                // the breadcrumb has no additional nodes.
901
                if ($currentnode && ($currentnode->key == $activenode->key && $currentnode->type == $activenode->type)) {
902
                    $showcoursemenu = true;
903
                }
904
            }
905
        }
906
 
907
        // This is the site front page.
908
        if (
909
            $context->contextlevel == CONTEXT_COURSE &&
910
            !empty($currentnode) &&
911
            $currentnode->key === 'home'
912
        ) {
913
            $showfrontpagemenu = true;
914
        }
915
 
916
        // This is the user profile page.
917
        if (
918
            $context->contextlevel == CONTEXT_USER &&
919
            !empty($currentnode) &&
920
            ($currentnode->key === 'myprofile')
921
        ) {
922
            $showusermenu = true;
923
        }
924
 
925
        if ($showfrontpagemenu) {
926
            $settingsnode = $this->page->settingsnav->find('frontpage', navigation_node::TYPE_SETTING);
927
            if ($settingsnode) {
928
                // Build an action menu based on the visible nodes from this navigation tree.
929
                $skipped = $this->build_action_menu_from_navigation($menu, $settingsnode, false, true);
930
 
931
                // We only add a list to the full settings menu if we didn't include every node in the short menu.
932
                if ($skipped) {
933
                    $text = get_string('morenavigationlinks');
934
                    $url = new moodle_url('/course/admin.php', array('courseid' => $this->page->course->id));
935
                    $link = new action_link($url, $text, null, null, new pix_icon('t/edit', $text));
936
                    $menu->add_secondary_action($link);
937
                }
938
            }
939
        } else if ($showcoursemenu) {
940
            $settingsnode = $this->page->settingsnav->find('courseadmin', navigation_node::TYPE_COURSE);
941
            if ($settingsnode) {
942
                // Build an action menu based on the visible nodes from this navigation tree.
943
                $skipped = $this->build_action_menu_from_navigation($menu, $settingsnode, false, true);
944
 
945
                // We only add a list to the full settings menu if we didn't include every node in the short menu.
946
                if ($skipped) {
947
                    $text = get_string('morenavigationlinks');
948
                    $url = new moodle_url('/course/admin.php', array('courseid' => $this->page->course->id));
949
                    $link = new action_link($url, $text, null, null, new pix_icon('t/edit', $text));
950
                    $menu->add_secondary_action($link);
951
                }
952
            }
953
        } else if ($showusermenu) {
954
            // Get the course admin node from the settings navigation.
955
            $settingsnode = $this->page->settingsnav->find('useraccount', navigation_node::TYPE_CONTAINER);
956
            if ($settingsnode) {
957
                // Build an action menu based on the visible nodes from this navigation tree.
958
                $this->build_action_menu_from_navigation($menu, $settingsnode);
959
            }
960
        }
961
 
962
        return $this->render($menu);
963
    }
964
 
1441 ariadna 965
    public function customeditblockbtn() {
1 efrain 966
        $header = new stdClass();
967
        $header->settingsmenu = $this->context_header_settings_menu();
968
        $header->pageheadingbutton = $this->page_heading_button();
969
 
970
        $html = $this->render_from_template('theme_universe/header_settings_menu', $header);
971
 
972
        return $html;
973
    }
974
 
975
    /**
976
     * Renders the context header for the page.
977
     *
978
     * @param array $headerinfo Heading information.
979
     * @param int $headinglevel What 'h' level to make the heading.
980
     * @return string A rendered context header.
981
     */
1441 ariadna 982
    public function context_header($headerinfo = null, $headinglevel = 1): string {
1 efrain 983
        global $DB, $USER, $CFG, $SITE;
984
        require_once($CFG->dirroot . '/user/lib.php');
985
        $context = $this->page->context;
986
        $heading = null;
987
        $imagedata = null;
988
        $subheader = null;
989
        $userbuttons = null;
990
 
991
        // Make sure to use the heading if it has been set.
992
        if (isset($headerinfo['heading'])) {
993
            $heading = $headerinfo['heading'];
994
        } else {
995
            $heading = $this->page->heading;
996
        }
997
 
998
        // The user context currently has images and buttons. Other contexts may follow.
999
        if ((isset($headerinfo['user']) || $context->contextlevel == CONTEXT_USER) && $this->page->pagetype !== 'my-index') {
1000
            if (isset($headerinfo['user'])) {
1001
                $user = $headerinfo['user'];
1002
            } else {
1003
                // Look up the user information if it is not supplied.
1004
                $user = $DB->get_record('user', array('id' => $context->instanceid));
1005
            }
1006
 
1007
            // If the user context is set, then use that for capability checks.
1008
            if (isset($headerinfo['usercontext'])) {
1009
                $context = $headerinfo['usercontext'];
1010
            }
1011
 
1012
            // Only provide user information if the user is the current user, or a user which the current user can view.
1013
            // When checking user_can_view_profile(), either:
1014
            // If the page context is course, check the course context (from the page object) or;
1015
            // If page context is NOT course, then check across all courses.
1016
            $course = ($this->page->context->contextlevel == CONTEXT_COURSE) ? $this->page->course : null;
1017
 
1018
            if (user_can_view_profile($user, $course)) {
1019
                // Use the user's full name if the heading isn't set.
1020
                if (empty($heading)) {
1021
                    $heading = fullname($user);
1022
                }
1023
 
1024
                $imagedata = $this->user_picture($user, array('size' => 100));
1025
 
1026
                // Check to see if we should be displaying a message button.
1027
                if (!empty($CFG->messaging) && has_capability('moodle/site:sendmessage', $context)) {
1028
                    $userbuttons = array(
1029
                        'messages' => array(
1030
                            'buttontype' => 'message',
1031
                            'title' => get_string('message', 'message'),
1441 ariadna 1032
                            'url' => new moodle_url('/message/index.php', ['id' => $user->id]),
1033
                            'image' => 't/message',
1 efrain 1034
                            'linkattributes' => \core_message\helper::messageuser_link_params($user->id),
1035
                            'page' => $this->page
1036
                        )
1037
                    );
1038
 
1039
                    if ($USER->id != $user->id) {
1040
                        $iscontact = \core_message\api::is_contact($USER->id, $user->id);
1041
                        $contacttitle = $iscontact ? 'removefromyourcontacts' : 'addtoyourcontacts';
1441 ariadna 1042
                        $contacturlaction = $iscontact ? 't/removecontact' : 't/addcontact';
1043
                        $contactimage = $iscontact ? 't/removecontact' : 't/addcontact';
1 efrain 1044
                        $userbuttons['togglecontact'] = array(
1045
                            'buttontype' => 'togglecontact',
1046
                            'title' => get_string($contacttitle, 'message'),
1047
                            'url' => new moodle_url(
1048
                                '/message/index.php',
1049
                                array(
1050
                                    'user1' => $USER->id,
1051
                                    'user2' => $user->id,
1052
                                    $contacturlaction => $user->id,
1053
                                    'sesskey' => sesskey()
1054
                                )
1055
                            ),
1056
                            'image' => $contactimage,
1057
                            'linkattributes' => \core_message\helper::togglecontact_link_params($user, $iscontact),
1058
                            'page' => $this->page
1059
                        );
1060
                    }
1061
 
1062
                    $this->page->requires->string_for_js('changesmadereallygoaway', 'moodle');
1063
                }
1064
            } else {
1065
                $heading = null;
1066
            }
1067
        }
1068
 
1069
        $prefix = null;
1070
        if ($context->contextlevel == CONTEXT_MODULE) {
1071
            if ($this->page->course->format === 'singleactivity') {
1072
                $heading = $this->page->course->fullname;
1073
            } else {
1074
                $heading = $this->page->cm->get_formatted_name();
1075
                $imagedata = $this->pix_icon('monologo', '', $this->page->activityname, ['class' => 'activityicon']);
1076
                $purposeclass = plugin_supports('mod', $this->page->activityname, FEATURE_MOD_PURPOSE);
1077
                $purposeclass .= ' activityiconcontainer';
1078
                $purposeclass .= ' modicon_' . $this->page->activityname;
1079
                $imagedata = html_writer::tag('div', $imagedata, ['class' => $purposeclass]);
1080
                $prefix = get_string('modulename', $this->page->activityname);
1081
            }
1082
        }
1083
 
1084
        $contextheader = new \context_header($heading, $headinglevel, $imagedata, $userbuttons, $prefix);
1085
        return $this->render_context_header($contextheader);
1086
    }
1087
 
1088
 
1089
    /**
1090
     * Construct a user menu, returning HTML that can be echoed out by a
1091
     * layout file.
1092
     *
1093
     * @param stdClass $user A user object, usually $USER.
1094
     * @param bool $withlinks true if a dropdown should be built.
1095
     * @return string HTML fragment.
1096
     */
1441 ariadna 1097
    public function user_menu($user = null, $withlinks = null) {
1 efrain 1098
        global $USER, $CFG;
1099
        require_once($CFG->dirroot . '/user/lib.php');
1100
 
1101
        if (is_null($user)) {
1102
            $user = $USER;
1103
        }
1104
 
1105
        // Note: this behaviour is intended to match that of core_renderer::login_info,
1106
        // but should not be considered to be good practice; layout options are
1107
        // intended to be theme-specific. Please don't copy this snippet anywhere else.
1108
        if (is_null($withlinks)) {
1109
            $withlinks = empty($this->page->layout_options['nologinlinks']);
1110
        }
1111
 
1112
        // Add a class for when $withlinks is false.
1113
        $usermenuclasses = 'usermenu';
1114
        if (!$withlinks) {
1115
            $usermenuclasses .= ' withoutlinks';
1116
        }
1117
 
1118
        $returnstr = "";
1119
 
1120
        // If during initial install, return the empty return string.
1121
        if (during_initial_install()) {
1122
            return $returnstr;
1123
        }
1124
 
1125
        $loginpage = $this->is_login_page();
1126
        $loginurl = get_login_url();
1127
        // If not logged in, show the typical not-logged-in string.
1128
        if (!isloggedin()) {
1129
            if (!$loginpage) {
1441 ariadna 1130
                $returnstr .= "<a class=\"rui-topbar-btn rui-login-btn text-decoration-none\" href=\"$loginurl\"><span class=\"rui-login-btn-txt\">" .
1 efrain 1131
                    get_string('login') .
1132
                    '</span>
1133
                <svg class="ml-2" width="20" height="20" fill="none" viewBox="0 0 24 24">
1134
                <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
1135
                d="M9.75 8.75L13.25 12L9.75 15.25"></path>
1136
                <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
1137
                d="M9.75 4.75H17.25C18.3546 4.75 19.25 5.64543 19.25 6.75V17.25C19.25 18.3546 18.3546 19.25 17.25 19.25H9.75">
1138
                </path>
1139
                <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 12H4.75"></path>
1140
                </svg></a>';
1141
            }
1142
            return html_writer::div(
1143
                html_writer::span(
1144
                    $returnstr,
1145
                    'login'
1146
                ),
1147
                $usermenuclasses
1148
            );
1149
        }
1150
 
1151
        // If logged in as a guest user, show a string to that effect.
1152
        if (isguestuser()) {
1153
            $icon = '<svg class="mr-2"
1154
                width="24"
1155
                height="24"
1156
                viewBox="0 0 24 24"
1157
                fill="none"
1158
                xmlns="http://www.w3.org/2000/svg">
1159
            <path d="M10 12C10 12.5523 9.55228 13 9 13C8.44772 13 8 12.5523 8
1160
            12C8 11.4477 8.44772 11 9 11C9.55228 11 10 11.4477 10 12Z"
1161
                fill="currentColor"
1162
                />
1163
            <path d="M15 13C15.5523 13 16 12.5523 16 12C16 11.4477 15.5523 11
1164
            15 11C14.4477 11 14 11.4477 14 12C14 12.5523 14.4477 13 15 13Z"
1165
                fill="currentColor"
1166
                />
1167
            <path fill-rule="evenodd"
1168
                clip-rule="evenodd"
1169
                d="M12.0244 2.00003L12 2C6.47715 2 2 6.47715 2 12C2 17.5228
1170
                6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.74235
1171
            17.9425 2.43237 12.788 2.03059L12.7886 2.0282C12.5329 2.00891
1172
            12.278 1.99961 12.0244 2.00003ZM12 20C16.4183 20 20 16.4183 20
1173
            12C20 11.3014 19.9105 10.6237 19.7422
1174
            9.97775C16.1597 10.2313 12.7359 8.52461 10.7605 5.60246C9.31322
1175
            7.07886 7.2982 7.99666 5.06879 8.00253C4.38902 9.17866 4 10.5439 4
1176
            12C4 16.4183 7.58172 20
1177
            12 20ZM11.9785 4.00003L12.0236 4.00003L12 4L11.9785 4.00003Z"
1178
                fill="currentColor"
1179
                /></svg>';
1180
            $returnstr = '<div class="rui-badge-guest">' . $icon . get_string('loggedinasguest') . '</div>';
1181
            if (!$loginpage && $withlinks) {
1441 ariadna 1182
                $returnstr .= "<a class=\"text-decoration-none rui-topbar-btn rui-login-btn\"
1 efrain 1183
                    href=\"$loginurl\"><span class=\"rui-login-btn-txt\">" .
1184
                    get_string('login') .
1185
                    '</span>
1186
                <svg class="ml-2"
1187
                    width="20"
1188
                    height="20"
1189
                    fill="none"
1190
                    viewBox="0 0 24 24">
1191
                <path stroke="currentColor"
1192
                    stroke-linecap="round"
1193
                    stroke-linejoin="round"
1194
                    stroke-width="2"
1195
                    d="M9.75 8.75L13.25 12L9.75 15.25"></path>
1196
                <path stroke="currentColor"
1197
                    stroke-linecap="round"
1198
                    stroke-linejoin="round"
1199
                    stroke-width="2"
1200
                    d="M9.75 4.75H17.25C18.3546 4.75 19.25 5.64543 19.25
1201
                    6.75V17.25C19.25 18.3546 18.3546 19.25 17.25 19.25H9.75"></path>
1202
                    <path stroke="currentColor"
1203
                        stroke-linecap="round"
1204
                        stroke-linejoin="round"
1205
                        stroke-width="2"
1206
                        d="M13 12H4.75"></path></svg></a>';
1207
            }
1208
 
1209
            return html_writer::div(
1210
                html_writer::span(
1211
                    $returnstr,
1212
                    'login'
1213
                ),
1214
                $usermenuclasses
1215
            );
1216
        }
1217
 
1218
        // Get some navigation opts.
1219
        $opts = user_get_user_navigation_info($user, $this->page, array('avatarsize' => 56));
1220
 
1221
        $avatarclasses = "avatars";
1222
        $avatarcontents = html_writer::span($opts->metadata['useravatar'], 'avatar current');
1223
        $usertextcontents = '<span class="rui-fullname">' . $opts->metadata['userfullname'] . '</span>';
1224
        $usertextmail = $user->email;
1225
        $usernick = '<svg class="mr-1"
1226
            width="16"
1227
            height="16"
1228
            fill="none"
1229
            viewBox="0 0 24 24">
1230
        <path stroke="currentColor"
1231
            stroke-linecap="round"
1232
            stroke-linejoin="round"
1233
            stroke-width="2"
1234
            d="M12 13V15"></path>
1235
        <circle cx="12"
1236
            cy="9"
1237
            r="1"
1238
            fill="currentColor"></circle>
1239
        <circle cx="12"
1240
            cy="12"
1241
            r="7.25"
1242
            stroke="currentColor"
1243
            stroke-linecap="round"
1244
            stroke-linejoin="round"
1245
            stroke-width="1.5"></circle>
1246
        </svg>' . $user->username;
1247
 
1248
        // Other user.
1249
        $usermeta = '';
1250
        if (!empty($opts->metadata['asotheruser'])) {
1251
            $avatarcontents .= html_writer::span(
1252
                $opts->metadata['realuseravatar'],
1253
                'avatar realuser'
1254
            );
1255
            $usermeta .= $opts->metadata['realuserfullname'];
1256
            $usermeta .= html_writer::tag(
1257
                'span',
1258
                get_string(
1259
                    'loggedinas',
1260
                    'moodle',
1261
                    html_writer::span(
1262
                        $opts->metadata['userfullname'],
1263
                        'value'
1264
                    )
1265
                ),
1266
                array('class' => 'meta viewingas')
1267
            );
1268
        }
1269
 
1270
        // Role.
1271
        if (!empty($opts->metadata['asotherrole'])) {
1272
            $role = core_text::strtolower(preg_replace('#[ ]+#', '-', trim($opts->metadata['rolename'])));
1273
            $usermeta .= html_writer::span(
1274
                $opts->metadata['rolename'],
1441 ariadna 1275
                "meta role role-$role"
1 efrain 1276
            );
1277
        }
1278
 
1279
        // User login failures.
1280
        if (!empty($opts->metadata['userloginfail'])) {
1281
            $usermeta .= html_writer::div(
1282
                '<svg class="mr-1"
1283
                width="16"
1284
                height="16"
1285
                fill="none"
1286
                viewBox="0 0 24 24"><path stroke="currentColor"
1287
                stroke-linecap="round"
1288
                stroke-linejoin="round"
1289
                stroke-width="1.5"
1290
                d="M4.9522 16.3536L10.2152 5.85658C10.9531 4.38481 13.0539
1291
                4.3852 13.7913 5.85723L19.0495 16.3543C19.7156 17.6841 18.7487
1292
                19.25 17.2613 19.25H6.74007C5.25234
1293
                19.25 4.2854 17.6835 4.9522 16.3536Z">
1294
                </path><path stroke="currentColor"
1295
                stroke-linecap="round"
1296
                stroke-linejoin="round"
1297
                stroke-width="2"
1298
                d="M12 10V12"></path>
1299
                <circle cx="12" cy="16" r="1" fill="currentColor"></circle></svg>' .
1300
                    $opts->metadata['userloginfail'],
1301
                'meta loginfailures'
1302
            );
1303
        }
1304
 
1305
        // MNet.
1306
        if (!empty($opts->metadata['asmnetuser'])) {
1307
            $mnet = strtolower(preg_replace('#[ ]+#', '-', trim($opts->metadata['mnetidprovidername'])));
1308
            $usermeta .= html_writer::span(
1309
                $opts->metadata['mnetidprovidername'],
1310
                'meta mnet mnet-' . $mnet
1311
            );
1312
        }
1313
 
1314
        $returnstr .= html_writer::span(
1315
            html_writer::span($avatarcontents, $avatarclasses),
1316
            'userbutton'
1317
        );
1318
 
1319
        // Create a divider (well, a filler).
1320
        $divider = new action_menu_filler();
1321
        $divider->primary = false;
1322
 
1323
        $am = new action_menu();
1324
        $am->set_menu_trigger(
1325
            $returnstr
1326
        );
1327
        $am->set_action_label(get_string('usermenu'));
1328
        $am->set_nowrap_on_items();
1329
 
1330
        if ($CFG->enabledashboard) {
1331
            $dashboardlink = '<div class="dropdown-item-wrapper"><a class="dropdown-item" href="' .
1332
                new moodle_url('/my/') .
1333
                '" data-identifier="dashboard,moodle" title="dashboard,moodle">' .
1334
                get_string('myhome', 'moodle') .
1335
                '</a></div>';
1336
        } else {
1337
            $dashboardlink = null;
1338
        }
1339
 
1340
        $am->add(
1341
            '<div class="dropdown-user-wrapper"><div class="dropdown-user">' . $usertextcontents  . '</div>'
1342
                . '<div class="dropdown-user-mail text-truncate" title="' . $usertextmail . '">' . $usertextmail . '</div>'
1343
                . '<span class="dropdown-user-nick w-100">' . $usernick . '</span>'
1344
                . '<div class="dropdown-user-meta"><span class="badge-xs badge-sq badge-warning flex-wrap">' .
1345
                $usermeta . '</span></div>'
1346
                . '</div><div class="dropdown-divider dropdown-divider-user"></div>' . $dashboardlink
1347
        );
1348
 
1349
        if ($withlinks) {
1350
            $navitemcount = count($opts->navitems);
1351
            $idx = 0;
1352
            foreach ($opts->navitems as $key => $value) {
1353
 
1354
                switch ($value->itemtype) {
1355
                    case 'divider':
1356
                        // If the nav item is a divider, add one and skip link processing.
1357
                        $am->add($divider);
1358
                        break;
1359
 
1360
                    case 'invalid':
1361
                        // Silently skip invalid entries (should we post a notification?).
1362
                        break;
1363
 
1364
                    case 'link':
1365
                        $al = '<a class="dropdown-item" href="' .
1366
                            $value->url .
1367
                            '" data-identifier="' .
1368
                            $value->titleidentifier .
1369
                            '" title="' .
1370
                            $value->titleidentifier .
1371
                            '">' .
1372
                            $value->title . '</a>';
1373
                        $am->add($al);
1374
                        break;
1375
                }
1376
 
1377
                $idx++;
1378
 
1379
                // Add dividers after the first item and before the last item.
1380
                if ($idx == 1 || $idx == $navitemcount - 1) {
1381
                    $am->add($divider);
1382
                }
1383
            }
1384
        }
1385
 
1386
        return html_writer::div(
1387
            $this->render($am),
1388
            $usermenuclasses
1389
        );
1390
    }
1391
 
1392
 
1393
    /**
1394
     * Returns standard main content placeholder.
1395
     * Designed to be called in theme layout.php files.
1396
     *
1397
     * @return string HTML fragment.
1398
     */
1441 ariadna 1399
    public function main_content() {
1400
        // This is here because it is the only place we can inject the "main" role over the entire main content area
1401
        // without requiring all theme's to manually do it, and without creating yet another thing people need to
1402
        // remember in the theme.
1403
        // This is an unfortunate hack. DO NO EVER add anything more here.
1404
        // DO NOT add classes.
1405
        // DO NOT add an id.
1406
        return '<div class="main-content" role="main">' . $this->unique_main_content_token . '</div>';
1 efrain 1407
    }
1408
 
1409
    /**
1410
     * Outputs a heading
1411
     *
1412
     * @param string $text The text of the heading
1413
     * @param int $level The level of importance of the heading. Defaulting to 2
1414
     * @param string $classes A space-separated list of CSS classes. Defaulting to null
1415
     * @param string $id An optional ID
1416
     * @return string the HTML to output.
1417
     */
1441 ariadna 1418
    public function heading($text, $level = 2, $classes = null, $id = null) {
1 efrain 1419
        $level = (int) $level;
1420
        if ($level < 1 || $level > 6) {
1421
            throw new coding_exception('Heading level must be an integer between 1 and 6.');
1422
        }
1423
        return html_writer::tag('div', html_writer::tag('h' .
1424
            $level, $text, array('id' => $id, 'class' => renderer_base::prepare_classes($classes) .
1425
            ' rui-main-content-title rui-main-content-title--h' .
1426
            $level)), array('class' => 'rui-title-container'));
1427
    }
1428
 
1429
 
1441 ariadna 1430
    public function headingwithavatar($text, $level = 2, $classes = null, $id = null) {
1 efrain 1431
        $level = (int) $level;
1432
        if ($level < 1 || $level > 6) {
1433
            throw new coding_exception('Heading level must be an integer between 1 and 6.');
1434
        }
1435
        return html_writer::tag('div', html_writer::tag('h' .
1436
            $level, $text, array('id' => $id, 'class' => renderer_base::prepare_classes($classes) .
1437
            ' rui-main-content-title-with-avatar')), array('class' => 'rui-title-container-with-avatar'));
1438
    }
1439
 
1440
    /**
1441
     * Renders the login form.
1442
     *
1443
     * @param \core_auth\output\login $form The renderable.
1444
     * @return string
1445
     */
1441 ariadna 1446
    public function render_login(\core_auth\output\login $form) {
1 efrain 1447
        global $CFG, $SITE;
1448
 
1449
        $context = $form->export_for_template($this);
1450
 
1451
        // Override because rendering is not supported in template yet.
1452
        if ($CFG->rememberusername == 0) {
1453
            $context->cookieshelpiconformatted = $this->help_icon('cookiesenabledonlysession');
1454
        } else {
1455
            $context->cookieshelpiconformatted = $this->help_icon('cookiesenabled');
1456
        }
1457
        $context->errorformatted = $this->error_text($context->error);
1458
        $url = $this->get_logo_url();
1459
        if ($url) {
1460
            $url = $url->out(false);
1461
        }
1462
        $context->logourl = $url;
1463
        $context->sitename = format_string(
1464
            $SITE->fullname,
1465
            true,
1466
            ['context' => context_course::instance(SITEID), "escape" => false]
1467
        );
1468
 
1441 ariadna 1469
        $setloginlayout = $this->page->theme->settings->setloginlayout;
1470
        switch ($setloginlayout) {
1471
            case 1:
1472
                $context->loginlayout1 = 1;
1473
                break;
1474
            case 2:
1475
                $context->loginlayout2 = 1;
1476
                if (isset($this->page->theme->settings->loginbg)) {
1477
                    $context->loginlayoutimg = 1;
1478
                }
1479
                break;
1480
            case 3:
1481
                $context->loginlayout3 = 1;
1482
                if (isset($this->page->theme->settings->loginbg)) {
1483
                    $context->loginlayoutimg = 1;
1484
                }
1485
                break;
1486
            case 4:
1487
                $context->loginlayout4 = 1;
1488
                break;
1489
            case 5:
1490
                $context->loginlayout5 = 1;
1491
                break;
1 efrain 1492
        }
1493
 
1494
        if (isset($this->page->theme->settings->loginlogooutside)) {
1495
            $context->loginlogooutside = $this->page->theme->settings->loginlogooutside;
1496
        }
1497
 
1498
        if (isset($this->page->theme->settings->customsignupoutside)) {
1499
            $context->customsignupoutside = $this->page->theme->settings->customsignupoutside;
1500
        }
1501
 
1502
        if (isset($this->page->theme->settings->loginidprovtop)) {
1503
            $context->loginidprovtop = $this->page->theme->settings->loginidprovtop;
1504
        }
1505
 
1506
        if (isset($this->page->theme->settings->stringca)) {
1507
            $context->stringca = format_text(($this->page->theme->settings->stringca),
1508
                FORMAT_HTML,
1509
                array('noclean' => true)
1510
            );
1511
        }
1512
 
1513
        if (isset($this->page->theme->settings->stringca)) {
1514
            $context->stringca = format_text(($this->page->theme->settings->stringca),
1515
                FORMAT_HTML,
1516
                array('noclean' => true)
1517
            );
1518
        }
1519
 
1520
        if (isset($this->page->theme->settings->loginhtmlcontent1)) {
1521
            $context->loginhtmlcontent1 = format_text(($this->page->theme->settings->loginhtmlcontent1),
1522
                FORMAT_HTML,
1523
                array('noclean' => true)
1524
            );
1525
        }
1526
 
1527
        if (isset($this->page->theme->settings->loginhtmlcontent2)) {
1528
            $context->loginhtmlcontent2 = format_text(($this->page->theme->settings->loginhtmlcontent2),
1529
                FORMAT_HTML,
1441 ariadna 1530
                ['noclean' => true]
1 efrain 1531
            );
1532
        }
1533
 
1534
        if (isset($this->page->theme->settings->loginhtmlcontent3)) {
1535
            $context->loginhtmlcontent3 = format_text(($this->page->theme->settings->loginhtmlcontent3),
1536
                FORMAT_HTML,
1441 ariadna 1537
                ['noclean' => true]
1 efrain 1538
            );
1539
        }
1540
 
1541
        if (isset($this->page->theme->settings->loginhtmlcontent2)) {
1542
            $context->loginhtmlcontent2 = format_text(($this->page->theme->settings->loginhtmlcontent2),
1543
                FORMAT_HTML,
1441 ariadna 1544
                ['noclean' => true]
1 efrain 1545
            );
1546
        }
1547
 
1548
        if (isset($this->page->theme->settings->logincustomfooterhtml)) {
1549
            $context->logincustomfooterhtml = format_text(($this->page->theme->settings->logincustomfooterhtml),
1550
                FORMAT_HTML,
1441 ariadna 1551
                ['noclean' => true]
1 efrain 1552
            );
1553
        }
1554
 
1555
        if (isset($this->page->theme->settings->loginhtmlblockbottom)) {
1556
            $context->loginhtmlblockbottom = format_text(($this->page->theme->settings->loginhtmlblockbottom),
1557
                FORMAT_HTML,
1441 ariadna 1558
                ['noclean' => true]
1 efrain 1559
            );
1560
        }
1561
 
1562
        if (isset($this->page->theme->settings->loginfootercontent)) {
1563
            $context->loginfootercontent = format_text(($this->page->theme->settings->loginfootercontent),
1564
                FORMAT_HTML,
1441 ariadna 1565
                ['noclean' => true]
1 efrain 1566
            );
1567
        }
1568
 
1569
        if (isset($this->page->theme->settings->footercopy)) {
1570
            $context->footercopy = format_text(($this->page->theme->settings->footercopy),
1571
                FORMAT_HTML,
1441 ariadna 1572
                ['noclean' => true]
1 efrain 1573
            );
1574
        }
1575
 
1576
        if (isset($this->page->theme->settings->loginintrotext)) {
1577
            $context->loginintrotext = format_text(($this->page->theme->settings->loginintrotext),
1578
                FORMAT_HTML,
1441 ariadna 1579
                ['noclean' => true]
1 efrain 1580
            );
1581
        }
1582
 
1583
        if (isset($this->page->theme->settings->loginintrotext)) {
1584
            $context->loginintrotext = format_text(($this->page->theme->settings->loginintrotext),
1585
                FORMAT_HTML,
1441 ariadna 1586
                ['noclean' => true]
1 efrain 1587
            );
1588
        }
1589
 
1590
        if (isset($this->page->theme->settings->customloginlogo)) {
1591
            $context->customloginlogo = $this->page->theme->setting_file_url('customloginlogo', 'customloginlogo');
1592
        }
1593
 
1594
        if (isset($this->page->theme->settings->loginbg)) {
1595
            $context->loginbg = $this->page->theme->setting_file_url('loginbg', 'loginbg');
1596
        }
1597
 
1598
        if (isset($this->page->theme->settings->hideforgotpassword)) {
1599
            $context->hideforgotpassword = $this->page->theme->settings->hideforgotpassword == 1;
1600
        }
1601
 
1602
        if (isset($this->page->theme->settings->logininfobox)) {
1603
            $context->logininfobox = format_text(($this->page->theme->settings->logininfobox),
1604
                FORMAT_HTML,
1605
                array('noclean' => true)
1606
            );
1607
        }
1608
 
1609
        return $this->render_from_template('core/loginform', $context);
1610
    }
1611
 
1612
    /**
1613
     * Render the login signup form into a nice template for the theme.
1614
     *
1615
     * @param mform $form
1616
     * @return string
1617
     */
1441 ariadna 1618
    public function render_login_signup_form($form) {
1 efrain 1619
        global $SITE;
1620
 
1621
        $context = $form->export_for_template($this);
1622
        $url = $this->get_logo_url();
1623
        if ($url) {
1624
            $url = $url->out(false);
1625
        }
1626
        $context['logourl'] = $url;
1627
        $context['sitename'] = format_string(
1628
            $SITE->fullname,
1629
            true,
1630
            ['context' => context_course::instance(SITEID), "escape" => false]
1631
        );
1632
 
1441 ariadna 1633
        $setloginlayout = $this->page->theme->settings->setloginlayout;
1634
 
1635
        switch ($setloginlayout) {
1636
            case 1:
1637
                $context['loginlayout1'] = 1;
1638
                break;
1639
            case 2:
1640
                $context['loginlayout2'] = 1;
1641
                if (isset($this->page->theme->settings->loginbg)) {
1642
                    $context['loginlayoutimg'] = 1;
1643
                }
1644
                break;
1645
            case 3:
1646
                $context['loginlayout3'] = 1;
1647
                if (isset($this->page->theme->settings->loginbg)) {
1648
                    $context['loginlayoutimg'] = 1;
1649
                }
1650
                break;
1651
            case 4:
1652
                $context['loginlayout4'] = 1;
1653
                break;
1654
            case 5:
1655
                $context['loginlayout5'] = 1;
1656
                break;
1 efrain 1657
        }
1658
 
1659
        if (isset($this->page->theme->settings->loginlogooutside)) {
1660
            $context['loginlogooutside'] = $this->page->theme->settings->loginlogooutside;
1661
        }
1662
 
1663
        if (isset($this->page->theme->settings->stringbacktologin)) {
1664
            $context['stringbacktologin'] = format_text(($this->page->theme->settings->stringbacktologin),
1665
                FORMAT_HTML,
1441 ariadna 1666
                ['noclean' => true]
1 efrain 1667
            );
1668
        }
1669
        if (isset($this->page->theme->settings->signupintrotext)) {
1670
            $context['signupintrotext'] = format_text(($this->page->theme->settings->signupintrotext),
1671
                FORMAT_HTML,
1441 ariadna 1672
                ['noclean' => true]
1 efrain 1673
            );
1674
        }
1675
        if (isset($this->page->theme->settings->signuptext)) {
1676
            $context['signuptext'] = format_text(($this->page->theme->settings->signuptext),
1677
                FORMAT_HTML,
1441 ariadna 1678
                ['noclean' => true]
1 efrain 1679
            );
1680
        }
1681
 
1682
        if (!empty($this->page->theme->settings->customloginlogo)) {
1683
            $url = $this->page->theme->setting_file_url('customloginlogo', 'customloginlogo');
1684
            $context['customloginlogo'] = $url;
1685
        }
1686
 
1687
        if (!empty($this->page->theme->settings->loginbg)) {
1688
            $url = $this->page->theme->setting_file_url('loginbg', 'loginbg');
1689
            $context['loginbg'] = $url;
1690
        }
1691
 
1692
        if (isset($this->page->theme->settings->loginfootercontent)) {
1693
            $context['loginfootercontent'] = format_text(($this->page->theme->settings->loginfootercontent),
1694
                FORMAT_HTML,
1441 ariadna 1695
                ['noclean' => true]
1 efrain 1696
            );
1697
        }
1698
 
1699
        return $this->render_from_template('core/signup_form_layout', $context);
1700
    }
1701
 
1702
 
1703
    /**
1704
     * Renders the header bar.
1705
     *
1706
     * @param context_header $contextheader Header bar object.
1707
     * @return string HTML for the header bar.
1708
     */
1441 ariadna 1709
    protected function render_context_header(\context_header $contextheader) {
1 efrain 1710
        $heading = null;
1711
        $imagedata = null;
1712
        $html = null;
1713
 
1714
        // Generate the heading first and before everything else as we might have to do an early return.
1715
        if (!isset($contextheader->heading)) {
1716
            $heading = $this->heading($this->page->heading, $contextheader->headinglevel);
1717
        } else {
1718
            $heading = $this->heading($contextheader->heading, $contextheader->headinglevel);
1719
        }
1720
 
1721
        // All the html stuff goes here.
1722
        $html = html_writer::start_div('page-context-header d-flex align-items-center flex-wrap');
1723
 
1724
        // Image data.
1725
        if (isset($contextheader->imagedata)) {
1726
            // Header specific image.
1727
            $html .= html_writer::div($contextheader->imagedata, 'page-header-image');
1728
        }
1729
 
1730
        // Headings.
1731
        if (isset($contextheader->prefix)) {
1732
            $prefix = html_writer::div($contextheader->prefix, 'text-muted text-uppercase small line-height-3');
1733
            $heading = $prefix . $heading;
1734
        }
1735
 
1736
        if (!isset($contextheader->heading)) {
1737
            $html .= html_writer::tag('h3', $heading, array('class' => 'rui-page-title rui-page-title--page'));
1738
        } else if (isset($contextheader->imagedata)) {
1739
            $html .= html_writer::tag(
1740
                'div',
1741
                $this->heading($contextheader->heading, 4),
1742
                array('class' => 'rui-page-title rui-page-title--icon')
1743
            );
1744
        } else {
1745
            $html .= html_writer::tag('h2', $heading, array('class' => 'page-header-headings
1746
                rui-page-title rui-page-title--context'));
1747
        }
1748
 
1749
        // Buttons.
1750
        if (isset($contextheader->additionalbuttons)) {
1751
            $html .= html_writer::start_div('btn-group header-button-group my-2 my-lg-0 ml-lg-4');
1752
            foreach ($contextheader->additionalbuttons as $button) {
1753
                if (!isset($button->page)) {
1754
                    // Include js for messaging.
1755
                    if ($button['buttontype'] === 'togglecontact') {
1756
                        \core_message\helper::togglecontact_requirejs();
1757
                    }
1758
                    if ($button['buttontype'] === 'message') {
1759
                        \core_message\helper::messageuser_requirejs();
1760
                    }
1761
                    $image = $this->pix_icon($button['formattedimage'], $button['title'], 'moodle', array(
1762
                        'class' => 'iconsmall',
1763
                        'role' => 'presentation'
1764
                    ));
1765
                    $image .= html_writer::span($button['title'], 'header-button-title');
1766
                } else {
1767
                    $image = html_writer::empty_tag('img', array(
1768
                        'src' => $button['formattedimage'],
1769
                        'role' => 'presentation'
1770
                    ));
1771
                }
1772
                $html .= html_writer::link($button['url'], html_writer::tag('span', $image), $button['linkattributes']);
1773
            }
1774
            $html .= html_writer::end_div();
1775
        }
1776
        $html .= html_writer::end_div();
1777
 
1778
        return $html;
1779
    }
1780
 
1441 ariadna 1781
    public function header() {
1 efrain 1782
        global $USER, $COURSE;
1783
        $theme = theme_config::load('universe');
1784
 
1785
        $context = context_course::instance($COURSE->id);
1786
        $roles = get_user_roles($context, $USER->id, true);
1787
 
1788
        if (is_array($roles) && !empty($roles)) {
1789
            foreach ($roles as $role) {
1790
                $this->page->add_body_class('role-' . $role->shortname);
1791
            }
1792
        } else {
1793
            $this->page->add_body_class('role-none');
1794
        }
1795
 
1796
        if ($theme->settings->topbareditmode == '1') {
1797
            $this->page->add_body_class('rui-editmode--top');
1798
        } else {
1799
            $this->page->add_body_class('rui-editmode--footer');
1800
        }
1801
 
1802
        return parent::header();
1803
    }
1804
 
1805
 
1806
    /**
1807
     * See if this is the first view of the current cm in the session if it has fake blocks.
1808
     *
1809
     * (We track up to 100 cms so as not to overflow the session.)
1810
     * This is done for drawer regions containing fake blocks so we can show blocks automatically.
1811
     *
1812
     * @return boolean true if the page has fakeblocks and this is the first visit.
1813
     */
1441 ariadna 1814
    public function firstview_fakeblocks(): bool {
1 efrain 1815
        global $SESSION;
1816
 
1817
        $firstview = false;
1818
        if ($this->page->cm) {
1819
            if (!$this->page->blocks->region_has_fakeblocks('side-pre')) {
1820
                return false;
1821
            }
1822
            if (!property_exists($SESSION, 'firstview_fakeblocks')) {
1823
                $SESSION->firstview_fakeblocks = [];
1824
            }
1825
            if (array_key_exists($this->page->cm->id, $SESSION->firstview_fakeblocks)) {
1826
                $firstview = false;
1827
            } else {
1828
                $SESSION->firstview_fakeblocks[$this->page->cm->id] = true;
1829
                $firstview = true;
1830
                if (count($SESSION->firstview_fakeblocks) > 100) {
1831
                    array_shift($SESSION->firstview_fakeblocks);
1832
                }
1833
            }
1834
        }
1835
        return $firstview;
1836
    }
1837
 
1838
 
1839
    /**
1840
     * Build the guest access hint HTML code.
1841
     *
1842
     * @param int $courseid The course ID.
1843
     * @return string.
1844
     */
1441 ariadna 1845
    public function theme_universe_get_course_guest_access_hint($courseid) {
1 efrain 1846
        global $CFG;
1847
        require_once($CFG->dirroot . '/enrol/self/lib.php');
1848
 
1849
        $html = '';
1850
        $instances = enrol_get_instances($courseid, true);
1851
        $plugins = enrol_get_plugins(true);
1852
        foreach ($instances as $instance) {
1853
            if (!isset($plugins[$instance->enrol])) {
1854
                continue;
1855
            }
1856
            $plugin = $plugins[$instance->enrol];
1857
            if ($plugin->show_enrolme_link($instance)) {
1858
                $html = html_writer::tag('div', get_string(
1859
                    'showhintcourseguestaccesssettinglink',
1860
                    'theme_universe',
1861
                    array('url' => $CFG->wwwroot . '/enrol/index.php?id=' . $courseid)
1862
                ));
1863
                break;
1864
            }
1865
        }
1866
 
1867
        return $html;
1868
    }
1869
 
1870
 
1871
    /**
1872
     * Color Customization
1873
     * @return string HTML fragment.
1874
     */
1441 ariadna 1875
    public function additional_head_html() {
1 efrain 1876
        global $SITE, $DB, $CFG, $COURSE, $PAGE;
1877
        $output = null;
1441 ariadna 1878
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
1879
            $customfieldid1 = $DB->get_record('customfield_field', array('shortname' => 'maincolor1'));
1880
            $mainthemecolor = $customfieldid1 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid1->id, 'instanceid' => $COURSE->id)) : null;
1881
            $customfieldid2 = $DB->get_record('customfield_field', array('shortname' => 'maincolor2'));
1882
            // $mainthemecolor2 = $customfieldid2 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid2->id, 'instanceid' => $COURSE->id)) : null;
1883
            $customfieldid3 = $DB->get_record('customfield_field', array('shortname' => 'topbarcolor'));
1884
            $topbarcolor = $customfieldid3 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid3->id, 'instanceid' => $COURSE->id)) : null;
1885
            $customfieldid4 = $DB->get_record('customfield_field', array('shortname' => 'dmtopbarcolor'));
1886
            $dmtopbarcolor = $customfieldid4 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid4->id, 'instanceid' => $COURSE->id)) : null;
1887
            // $customfieldid5 = $DB->get_record('customfield_field', array('shortname' => 'colortopbartext'));
1888
            // $colortopbartext = $customfieldid5 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid5->id, 'instanceid' => $COURSE->id)) : null;
1 efrain 1889
 
1441 ariadna 1890
            $customfieldid6 = $DB->get_record('customfield_field', array('shortname' => 'footertextcolor'));
1891
            $footertextcolor = $customfieldid6 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid6->id, 'instanceid' => $COURSE->id)) : null;
1892
 
1893
            $customfieldid7 = $DB->get_record('customfield_field', array('shortname' => 'footerbgcolor'));
1894
            $footercolor = $customfieldid7 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid7->id, 'instanceid' => $COURSE->id)) : null;
1895
 
1896
            $customfieldid8 = $DB->get_record('customfield_field', array('shortname' => 'topbarcolor2'));
1897
            $topbarcolor2 = $customfieldid8 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid8->id, 'instanceid' => $COURSE->id)) : null;
1898
 
1899
            $customfieldid9 = $DB->get_record('customfield_field', array('shortname' => 'dmtopbarcolor2'));
1900
            $dmtopbarcolor2 = $customfieldid9 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid9->id, 'instanceid' => $COURSE->id)) : null;
1901
 
1902
            $customfieldid10 = $DB->get_record('customfield_field', array('shortname' => 'topbartextcolor'));
1903
            $topbartextcolor = $customfieldid10 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid10->id, 'instanceid' => $COURSE->id)) : null;
1904
            $customfieldid11 = $DB->get_record('customfield_field', array('shortname' => 'topbartexthovercolor'));
1905
            $topbartexthovercolor = $customfieldid11 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid11->id, 'instanceid' => $COURSE->id)) : null;
1906
            $customfieldid12 = $DB->get_record('customfield_field', array('shortname' => 'topbarbghovercolor'));
1907
            $topbarbghovercolor = $customfieldid12 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid12->id, 'instanceid' => $COURSE->id)) : null;
1908
 
1909
            $customfieldid13 = $DB->get_record('customfield_field', array('shortname' => 'dmtopbartextcolor'));
1910
            $dmtopbartextcolor = $customfieldid13 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid13->id, 'instanceid' => $COURSE->id)) : null;
1911
            $customfieldid14 = $DB->get_record('customfield_field', array('shortname' => 'dmtopbartexthovercolor'));
1912
            $dmtopbartexthovercolor = $customfieldid14 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid14->id, 'instanceid' => $COURSE->id)) : null;
1913
            $customfieldid15 = $DB->get_record('customfield_field', array('shortname' => 'dmtopbarbghovercolor'));
1914
            $dmtopbarbghovercolor = $customfieldid15 ? $DB->get_record('customfield_data', array('fieldid' => $customfieldid15->id, 'instanceid' => $COURSE->id)) : null;
1915
 
1916
 
1917
            $css = ':root { ';
1918
            if ($mainthemecolor && !empty($mainthemecolor->value)) {
1919
                $css .= '--main-theme-color: ' . $mainthemecolor->value . '; ';
1920
                $css .= '--primary-color-100: ' . \theme_universe\toolbox::tint($mainthemecolor->value, .1) . '; ';
1921
                $css .= '--primary-color-200: ' . \theme_universe\toolbox::tint($mainthemecolor->value, .2) . '; ';
1922
                $css .= '--primary-color-300: ' . \theme_universe\toolbox::tint($mainthemecolor->value, .3) . '; ';
1923
                $css .= '--primary-color-400: ' . \theme_universe\toolbox::tint($mainthemecolor->value, .4) . '; ';
1924
                $css .= '--primary-color-500: ' . \theme_universe\toolbox::tint($mainthemecolor->value, .5) . '; ';
1925
                $css .= '--primary-color-700: ' . \theme_universe\toolbox::shade($mainthemecolor->value, .5) . '; ';
1926
                $css .= '--primary-color-800: ' . \theme_universe\toolbox::shade($mainthemecolor->value, .3) . '; ';
1927
                $css .= '--primary-color-900: ' . \theme_universe\toolbox::shade($mainthemecolor->value, .1) . '; ';
1928
                //$css .= '--main-theme-color-gradient: ' . $mainthemecolor->value . '; ';
1929
                $css .= '--btn-primary-color-bg: ' . $mainthemecolor->value . '; ';
1930
                $css .= '--btn-primary-color-bg-hover: ' . \theme_universe\toolbox::shade($mainthemecolor->value, .5) . '; ';
1931
                //$css .= '--main-theme-color-gradient-2: ' . ($mainthemecolor2 && !empty($mainthemecolor2->value) ? $mainthemecolor2->value :  \theme_universe\toolbox::shade($mainthemecolor->value, .3)) . '; ';
1 efrain 1932
            }
1933
 
1441 ariadna 1934
            if ($topbarcolor && !empty($topbarcolor->value)) {
1935
                $css .= '--topbar-color: ' . $topbarcolor->value . '; ';
1936
                $css .= '--dm-topbar-color: ' . ($dmtopbarcolor && !empty($dmtopbarcolor->value) ? $dmtopbarcolor->value : $dmtopbarcolor->value) . '; ';
1 efrain 1937
            }
1938
 
1441 ariadna 1939
            if ($topbarcolor2 && !empty($topbarcolor2->value)) {
1940
                $css .= '--topbar-color-2: ' . $topbarcolor2->value . '; ';
1 efrain 1941
            }
1942
 
1441 ariadna 1943
            if ($dmtopbarcolor2 && !empty($dmtopbarcolor2->value)) {
1944
                $css .= '--dm-topbar-color-2: ' . ($dmtopbarcolor2 && !empty($dmtopbarcolor2->value) ? $dmtopbarcolor2->value : $dmtopbarcolor2->value) . '; ';
1 efrain 1945
            }
1946
 
1441 ariadna 1947
            if ($topbartextcolor && !empty($topbartextcolor->value)) {
1948
                $css .= '--topbar-btn-text: ' . ($topbartextcolor && !empty($topbartextcolor->value) ? $topbartextcolor->value : $topbartextcolor->value) . '; ';
1949
            }
1 efrain 1950
 
1441 ariadna 1951
            if ($topbarbghovercolor && !empty($topbarbghovercolor->value)) {
1952
                $css .= '--topbar-btn-hover: ' . ($topbarbghovercolor && !empty($topbarbghovercolor->value) ? $topbarbghovercolor->value : $topbarbghovercolor->value) . '; ';
1 efrain 1953
            }
1954
 
1441 ariadna 1955
            if ($topbartexthovercolor && !empty($topbartexthovercolor->value)) {
1956
                $css .= '--topbar-btn-hover-text: ' . ($topbartexthovercolor && !empty($topbartexthovercolor->value) ? $topbartexthovercolor->value : $topbartexthovercolor->value) . '; ';
1957
            }
1 efrain 1958
 
1441 ariadna 1959
            if ($dmtopbartextcolor && !empty($dmtopbartextcolor->value)) {
1960
                $css .= '--dm-topbar-btn-text: ' . ($dmtopbartextcolor && !empty($dmtopbartextcolor->value) ? $dmtopbartextcolor->value : $dmtopbartextcolor->value) . '; ';
1961
            }
1 efrain 1962
 
1441 ariadna 1963
            if ($dmtopbarbghovercolor && !empty($dmtopbarbghovercolor->value)) {
1964
                $css .= '--dm-topbar-btn-hover: ' . ($dmtopbarbghovercolor && !empty($dmtopbarbghovercolor->value) ? $dmtopbarbghovercolor->value : $dmtopbarbghovercolor->value) . '; ';
1965
            }
1 efrain 1966
 
1441 ariadna 1967
            if ($dmtopbartexthovercolor && !empty($dmtopbartexthovercolor->value)) {
1968
                $css .= '--dm-topbar-btn-hover-text: ' . ($dmtopbartexthovercolor && !empty($dmtopbartexthovercolor->value) ? $dmtopbartexthovercolor->value : $dmtopbartexthovercolor->value) . '; ';
1 efrain 1969
            }
1970
 
1441 ariadna 1971
            if ($footercolor && !empty($footercolor->value)) {
1972
                $css .= '--footer-color: ' . $footercolor->value . '; ';
1 efrain 1973
            }
1974
 
1441 ariadna 1975
            if ($footertextcolor && !empty($footertextcolor->value)) {
1976
                $css .= '--footer-text-color: ' . $footertextcolor->value . '; ';
1 efrain 1977
            }
1978
 
1979
            $css .= '}';
1980
            if ($css) {
1981
                $output .= '<style>' . $css . '</style>';
1982
            }
1983
        }
1984
        return $output;
1985
    }
1986
 
1441 ariadna 1987
    public function custom_course_logo() {
1 efrain 1988
        global $DB, $CFG, $COURSE, $PAGE;
1989
 
1990
        $output = null;
1991
 
1992
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
1993
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcourselogo'))) {
1994
                // Get custom field ID
1995
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcourselogo'));
1996
                $customfieldpicid = $customfieldpic->id;
1997
                // Get value
1998
                $customlogo = $DB->get_record(
1999
                    'customfield_data',
2000
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
2001
                );
2002
 
2003
                $customlogoid = $customlogo->id;
2004
                $contextid = $customlogo->contextid;
2005
 
2006
                if ($customfieldpic != null) {
2007
                    $files = get_file_storage()->get_area_files(
2008
                        $contextid,
2009
                        'customfield_picture',
2010
                        'file',
2011
                        $customlogoid,
2012
                        '',
2013
                        false
2014
                    );
2015
 
2016
                    if (empty($files)) {
2017
                        return null;
2018
                    }
2019
 
2020
                    $file = reset($files);
2021
                    $fileurl = moodle_url::make_pluginfile_url(
2022
                        $file->get_contextid(),
2023
                        $file->get_component(),
2024
                        $file->get_filearea(),
2025
                        $file->get_itemid(),
2026
                        $file->get_filepath(),
2027
                        $file->get_filename()
2028
                    );
2029
 
2030
                    $output .= $fileurl;
2031
                }
2032
            }
2033
        }
2034
 
2035
        return $output;
2036
    }
2037
 
1441 ariadna 2038
    public function custom_course_dmlogo() {
1 efrain 2039
        global $DB, $CFG, $COURSE, $PAGE;
2040
 
2041
        $output = null;
2042
 
2043
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2044
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursedmlogo'))) {
2045
                // Get custom field ID
2046
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcoursedmlogo'));
2047
                $customfieldpicid = $customfieldpic->id;
2048
                // Get value
2049
                $customlogo = $DB->get_record(
2050
                    'customfield_data',
2051
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
2052
                );
2053
 
2054
                $customlogoid = $customlogo->id;
2055
                $contextid = $customlogo->contextid;
2056
 
2057
                if ($customfieldpic != null) {
2058
                    $files = get_file_storage()->get_area_files(
2059
                        $contextid,
2060
                        'customfield_picture',
2061
                        'file',
2062
                        $customlogoid,
2063
                        '',
2064
                        false
2065
                    );
2066
 
2067
                    if (empty($files)) {
2068
                        return null;
2069
                    }
2070
 
2071
                    $file = reset($files);
2072
                    $fileurl = moodle_url::make_pluginfile_url(
2073
                        $file->get_contextid(),
2074
                        $file->get_component(),
2075
                        $file->get_filearea(),
2076
                        $file->get_itemid(),
2077
                        $file->get_filepath(),
2078
                        $file->get_filename()
2079
                    );
2080
 
2081
                    $output .= $fileurl;
2082
                }
2083
            }
1441 ariadna 2084
            return $output;
1 efrain 2085
        }
2086
    }
2087
 
1441 ariadna 2088
    public function custom_course_favicon() {
1 efrain 2089
        global $DB, $CFG, $COURSE, $PAGE;
2090
 
2091
        $output = null;
2092
 
2093
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2094
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursefavicon'))) {
2095
                // Get custom field ID
2096
                $customfieldpic = $DB->get_record('customfield_field', array('shortname' => 'customcoursefavicon'));
2097
                $customfieldpicid = $customfieldpic->id;
2098
                // Get value
2099
                $customfavicon = $DB->get_record(
2100
                    'customfield_data',
2101
                    array('fieldid' => $customfieldpicid, 'instanceid' => $COURSE->id)
2102
                );
2103
 
2104
                $customfaviconid = $customfavicon->id;
2105
                $contextid = $customfavicon->contextid;
2106
 
2107
                if ($customfieldpic != null) {
2108
                    $files = get_file_storage()->get_area_files(
2109
                        $contextid,
2110
                        'customfield_picture',
2111
                        'file',
2112
                        $customfaviconid,
2113
                        '',
2114
                        false
2115
                    );
2116
 
2117
                    if (empty($files)) {
2118
                        return null;
2119
                    }
2120
 
2121
                    $file = reset($files);
2122
                    $fileurl = moodle_url::make_pluginfile_url(
2123
                        $file->get_contextid(),
2124
                        $file->get_component(),
2125
                        $file->get_filearea(),
2126
                        $file->get_itemid(),
2127
                        $file->get_filepath(),
2128
                        $file->get_filename()
2129
                    );
2130
 
2131
                    $output .= $fileurl;
2132
                }
2133
            }
2134
        }
2135
 
2136
        return $output;
2137
    }
2138
 
1441 ariadna 2139
    public function custom_course_name() {
1 efrain 2140
        global $DB, $CFG, $COURSE, $PAGE;
2141
 
2142
        $output = null;
2143
 
2144
        if ($PAGE->pagelayout == 'course' || $PAGE->pagelayout == 'incourse') {
2145
            if ($DB->record_exists('customfield_field', array('shortname' => 'customcoursename'), 'id')) {
2146
                // Get custom field by name
2147
                $customfieldid = $DB->get_record('customfield_field', array('shortname' => 'customcoursename'));
2148
                // Get value
2149
                $customcoursename = $DB->get_record('customfield_data', array('fieldid' => $customfieldid->id, 'instanceid' => $COURSE->id));
2150
                if (!empty($customcoursename)) {
2151
                    $output .= $customcoursename->value;
2152
                }
2153
            } else {
2154
                $customcoursename = null;
2155
            }
2156
        }
2157
 
2158
        return $output;
2159
    }
2160
 
161 ariadna 2161
    /**
1 efrain 2162
     * Get the course pattern datauri to show on a course card.
2163
     *
2164
     * The datauri is an encoded svg that can be passed as a url.
2165
     * @param int $id Id to use when generating the pattern
2166
     * @return string datauri
2167
     */
1441 ariadna 2168
    public function get_generated_image_for_id($id) {
1 efrain 2169
        global $CFG;
2170
 
2171
        $theme = \theme_config::load('universe');
2172
        // Add custom course cover.
2173
        $customcover = $theme->setting_file_url('defaultcourseimg', 'defaultcourseimg');
2174
 
2175
        if (!empty(($customcover))) {
2176
            $urlreplace = preg_replace('|^https?://|i', '//', $CFG->wwwroot);
2177
            $customcover = str_replace($urlreplace, '', $customcover);
2178
            $txt = new moodle_url($customcover);
2179
            return strval($txt);
2180
        } else {
2181
            $color = $this->get_generated_color_for_id($id);
2182
            $pattern = new \core_geopattern();
2183
            $pattern->setColor($color);
2184
            $pattern->patternbyid($id);
2185
            return $pattern->datauri();
2186
        }
2187
    }
161 ariadna 2188
 
1441 ariadna 2189
    public function moremenu_group_item() {
1 efrain 2190
        global $CFG, $COURSE;
2191
 
2192
        $courseid = $COURSE->id;
2193
        $sitehomeurl = new moodle_url('/');
2194
 
2195
        if ($this->page->theme->settings->secnavgroupitem == 1) {
2196
            if (has_capability('moodle/course:managegroups', \context_course::instance($COURSE->id))) {
2197
                $html = $sitehomeurl . "group/index.php?id=" . $courseid;
2198
                return $html;
2199
            }
2200
        }
2201
    }
2202
 
1441 ariadna 2203
    public function moremenu_custom_items() {
1 efrain 2204
        global $CFG, $COURSE, $USER;
2205
 
2206
        $html = '';
2207
        $secnavcount = theme_universe_get_setting('secnavitemscount');
2208
 
1441 ariadna 2209
        // Get user role ID.
1 efrain 2210
        $context = context_course::instance($COURSE->id);
2211
        $roles = get_user_roles($context, $USER->id, true);
2212
        $role = key($roles);
2213
        if ($role != null) {
1441 ariadna 2214
            $roleid = $roles[$role]->id;
2215
        } else {
2216
            $roleid = 99;
1 efrain 2217
        }
2218
        // End.
2219
 
2220
        if ($this->page->theme->settings->secnavitems == 1) {
2221
 
2222
            $secnav = new stdClass();
2223
            for ($i = 1; $i <= $secnavcount; $i++) {
2224
                $secnav->title = theme_universe_get_setting("secnavcustomnavlabel" . $i);
2225
 
2226
                $url = theme_universe_get_setting("secnavcustomnavurl" . $i);
2227
                $courseid = $COURSE->id;
2228
                $newurl = str_replace("{{courseID}}", $courseid, $url);
1441 ariadna 2229
                $secnav->url = $newurl;
161 ariadna 2230
 
1 efrain 2231
                // User role restriction.
1441 ariadna 2232
                $selectrole = theme_universe_get_setting("secnavuserrole" . $i);
161 ariadna 2233
 
1441 ariadna 2234
                if ($selectrole == 1) {
2235
                    if ($roleid == 1 || $roleid == 2 || $roleid == 3 || $roleid == 4) {
2236
                        $secnav->isadmin = true;
2237
                        $secnav->nonrestriction = false;
2238
                    }
2239
                } else {
2240
                    $secnav->isadmin = false;
2241
                    $secnav->nonrestriction = true;
161 ariadna 2242
                }
1 efrain 2243
                // End.
2244
 
1441 ariadna 2245
                $html .= $this->render_from_template('theme_universe/custom_sec_nav_item', $secnav);
1 efrain 2246
            }
2247
        }
2248
        return $html;
2249
    }
1441 ariadna 2250
 
2251
    /**
2252
     *  Display only fields dedicated to enrollment page
2253
     */
2254
    public function get_enrollfields() {
2255
        global $COURSE;
2256
        $course = get_course($COURSE->id);
2257
 
2258
        $courseelement = new \core_course_list_element($course);
2259
 
2260
        if ($courseelement->has_custom_fields()) {
2261
            $fields = $courseelement->get_custom_fields();
2262
            $content = '';
2263
 
2264
            foreach ($fields as $field) {
2265
                if (empty($field->get_value())) {
2266
                    continue;
2267
                }
2268
 
2269
                // Get field shortname
2270
                $customfieldname = $field->get_field()->get('name');
2271
                $customfieldvalue = $field->get_value();
2272
                $customfieldshortname =  $field->get_field()->get('shortname');
2273
 
2274
                // Array with custom fields which need to be hidden.
2275
                $hiddencustomfields = array("enrolldesc", "enrollvideo");
2276
                $hiddencftitles = array("tool_courserating");
2277
 
2278
                if (in_array($customfieldshortname, $hiddencustomfields)) {
2279
                    $content .= html_writer::start_tag('div', array('class' => 'rui-custom-field-box'));
2280
                    $content .= html_writer::tag('div', $customfieldvalue, array('class' => 'rui-custom-field-value'));
2281
                    $content .= html_writer::end_tag('div');
2282
                }
2283
            }
2284
            return $content;
2285
        } else {
2286
            return false;
2287
        }
2288
    }
2289
 
2290
    public function show_course_filter() {
2291
        global $CFG;
2292
 
2293
        $showcoursefilter = $this->page->theme->settings->showcoursefilter;
2294
 
2295
        $siteurl = $CFG->wwwroot;
2296
        $currentUrl = $this->page->url->out(false);
2297
        $compareString = $siteurl . '/course/index.php';
2298
 
2299
        // Check if the current URL starts with the compare string
2300
        if (strpos($currentUrl, $compareString) === 0 && $showcoursefilter == 1) {
2301
            // Now, check if the length of the current URL is exactly the same as the compare string
2302
            if (strlen($currentUrl) == strlen($compareString)) {
2303
                // The current URL matches 'course/index.php'.
2304
                return false;
2305
            } else {
2306
                // The current URL matches 'course/index.php' but has additional content appended.
2307
                return true;
2308
            }
2309
        } else {
2310
            // The current URL does not match 'course/index.php'.
2311
            return true;
2312
        }
2313
    }
2314
 
2315
    /**
2316
     *
2317
     * Returns list of languages.
2318
     *
2319
     */
2320
    public function course_lang_list() {
2321
        $langs = get_string_manager()->get_list_of_translations();
2322
 
2323
        $output = '';
2324
 
2325
        foreach ((array)$langs as $langtype => $langname) {
2326
            $total = html_writer::empty_tag('span', array('class' => 'total'));
2327
            $output .= html_writer::div($langname . $total, 'filtering-filter', array('data-filter-name' => $langtype));
2328
        }
2329
 
2330
        return $output;
2331
    }
2332
 
2333
 
2334
 
2335
    /**
2336
     *
2337
     * Returns list of teachers.
2338
     *
2339
     */
2340
    function course_teachers_list() {
2341
        global $DB, $CFG, $COURSE;
2342
 
2343
        $output = null;
2344
 
2345
        $uniqueTeachers = [];
2346
 
2347
        // Get the current page URL.
2348
        //$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
2349
        $currentURL = $_SERVER['REQUEST_URI'];
2350
        // Parse the URL and extract the query string.
2351
        $query_str = parse_url($currentURL, PHP_URL_QUERY);
2352
        // Parse the query string into an associative array.
2353
        parse_str($query_str, $query_params);
2354
        // Get the category ID.
2355
        $categoryid = $query_params['categoryid'] ?? 'Category ID not found';
2356
        // End - Get the current page URL.
2357
 
2358
        // Fetch the course details
2359
        $courses = $DB->get_records('course', ['category' => $categoryid]);
2360
 
2361
        // Iterate over each course
2362
        foreach ($courses as $course) {
2363
            // Get context of the current course
2364
            $context = context_course::instance($course->id);
2365
 
2366
            // Get all users with the teacher role in the current course
2367
            $teachers = get_role_users(3, $context) + get_role_users(4, $context); // Teacher role ID is 3 and 4, adjust if necessary
2368
 
2369
            if (isset($teachers) && is_array($teachers)) {
2370
                // Iterate through the list of teachers for the current course
2371
                foreach ($teachers as $teacher) {
2372
                    // Check if the teacher ID already exists in the uniqueTeachers array
2373
                    if (!isset($uniqueTeachers[$teacher->id])) {
2374
                        // If the teacher ID does not exist, add it to the uniqueTeachers array
2375
                        $uniqueTeachers[$teacher->id] = $teacher;
2376
                    }
2377
                }
2378
            } else {
2379
                $uniqueTeachers = null;
2380
            }
2381
        }
2382
 
2383
        if (!empty($uniqueTeachers)) {
2384
            // Output the list of unique teachers
2385
            foreach ($uniqueTeachers as $teacher) {
2386
                $total = html_writer::empty_tag('span', ['class' => 'total']);
2387
                $teachername = "{$teacher->firstname} {$teacher->lastname}";
2388
                $output .= html_writer::div("$teachername$total", 'filtering-filter', ['data-filter-name' => $teachername]);
2389
            }
2390
 
2391
            return $output;
2392
        }
2393
    }
2394
 
2395
    /**
2396
     *
2397
     * Returns custom filter list based on parameters.
2398
     *
2399
     * @param string $filterNameSetting The name of the filter setting.
2400
     * @param string $filterShowSetting The show filter setting.
2401
     * @return string The HTML output for the filter list.
2402
     */
2403
    function get_course_customfilter_list($filterNameSetting, $filterShowSetting) {
2404
        global $DB, $COURSE;
2405
 
2406
        // Theme Settings.
2407
        $coursefilteron = $this->page->theme->settings->$filterShowSetting;
2408
        $customfiltername = $this->page->theme->settings->$filterNameSetting;
2409
 
2410
        if ($coursefilteron == 1 && $customfiltername != null) {
2411
            // Variables.
2412
            $fieldsarr = [];
2413
            $uniqueFields = [];
2414
            $filtertitle = '';
2415
            $record = $DB->get_record('customfield_field', ['shortname' => $customfiltername]);
2416
 
2417
            // Get the current page URL.
2418
            //$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
2419
            $currentURL = $_SERVER['REQUEST_URI'];
2420
            // Parse the URL and extract the query string.
2421
            $query_str = parse_url($currentURL, PHP_URL_QUERY);
2422
            // Parse the query string into an associative array.
2423
            parse_str($query_str, $query_params);
2424
            // Get the category ID.
2425
            $categoryid = $query_params['categoryid'] ?? 'Category ID not found';
2426
            // End - Get the current page URL.
2427
 
2428
            // Fetch the course details.
2429
            $courses = $DB->get_records('course', ['category' => $categoryid]);
2430
 
2431
            // Iterate over each course.
2432
            foreach ($courses as $course) {
2433
                // Get custom fields.
2434
                $courseelement = new core_course_list_element($course);
2435
                $fields = $courseelement->get_custom_fields();
2436
 
2437
                foreach ($fields as $field) {
2438
                    if (empty($field->get_value())) {
2439
                        continue;
2440
                    }
2441
 
2442
                    $customfieldshortname = $field->get_field()->get('shortname');
2443
                    $customfieldtype = $field->get_field()->get('type');
2444
 
2445
                    if ($customfieldshortname == $customfiltername) {
2446
                        if (str_contains($field->get_value(), ',')) {
2447
                            $itemsArray = explode(",", $field->get_value());
2448
                            foreach ($itemsArray as $item) {
2449
                                $uniqueFields[$item] = $item;
2450
                            }
2451
                        }
2452
                        if($customfieldtype === 'select') {
2453
 
2454
                            //$fieldid = $DB->get_record('customfield_field', ['id' => $record->fieldid]);
2455
                            $jsonString = $record->configdata;
2456
 
2457
                            // Decode JSON string into a PHP associative array
2458
                            $array = json_decode($jsonString, true);
2459
                            // Check if decoding was successful
2460
                            if (json_last_error() === JSON_ERROR_NONE) {
2461
                                // Access the 'options' key
2462
                                $options = $array['options'];
2463
                            } else {
2464
                                // Handle JSON decoding error
2465
                                echo "Error decoding JSON: " . json_last_error_msg();
2466
                            }
2467
                            $optionsArray = explode("\r\n", $options);
2468
                            $temp = $field->get_value() - 1;
2469
                            if($temp >= 0) {
2470
                                $uniqueFields[$field->get_value()] = $optionsArray[$temp];
2471
                            }
2472
                        } else {
2473
                            $uniqueFields[$field->get_value()] = $field->get_value();
2474
                        }
2475
 
2476
                    }
2477
                }
2478
            }
2479
 
2480
            // Filter - List.
2481
            if ($record != null) {
2482
                // Output the list of unique fields.
2483
                foreach ($uniqueFields as $field) {
2484
                    $fieldsarr[] = format_string($field);
2485
                }
2486
 
2487
                // Filter - Title.
2488
                $filtertitle = $record->name;
2489
            }
2490
 
2491
            $filtergroupno = $customfiltername;
2492
 
2493
            // Filter - Template.
2494
            $coursefilter = new stdClass();
2495
            $coursefilter->shortname = $customfiltername;
2496
            $coursefilter->filtergroupno = format_string($filtergroupno);
2497
            $coursefilter->title = format_string($filtertitle);
2498
            $coursefilter->item = $fieldsarr;
2499
 
2500
            return $this->render_from_template('theme_universe/course_filter_item', $coursefilter);
2501
        }
2502
    }
2503
 
2504
    /**
2505
     *
2506
     * Returns list #1.
2507
     *
2508
     */
2509
    public function course_customfilter1_list() {
2510
        return $this->get_course_customfilter_list('customfilter1', 'showfilter1', 'customfilter1');
2511
    }
2512
 
2513
    /**
2514
     *
2515
     * Returns list #2.
2516
     *
2517
     */
2518
    public function course_customfilter2_list() {
2519
        return $this->get_course_customfilter_list('customfilter2', 'showfilter2', 'customfilter2');
2520
    }
2521
 
2522
    /**
2523
     *
2524
     * Returns list #3.
2525
     *
2526
     */
2527
    public function course_customfilter3_list() {
2528
        return $this->get_course_customfilter_list('customfilter3', 'showfilter3', 'customfilter3');
2529
    }
2530
 
2531
    /**
2532
     *
2533
     * Returns list #4.
2534
     *
2535
     */
2536
    public function course_customfilter4_list() {
2537
        return $this->get_course_customfilter_list('customfilter4', 'showfilter4', 'customfilter4');
2538
    }
2539
 
2540
    /**
2541
     *
2542
     * Returns list #5.
2543
     *
2544
     */
2545
    public function course_customfilter5_list() {
2546
        return $this->get_course_customfilter_list('customfilter5', 'showfilter5', 'customfilter5');
2547
    }
2548
 
2549
    /**
2550
     *
2551
     * Returns list #6.
2552
     *
2553
     */
2554
    public function course_customfilter6_list() {
2555
        return $this->get_course_customfilter_list('customfilter6', 'showfilter6', 'customfilter6');
2556
    }
1 efrain 2557
}